//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension PaymentCryptographyData {
    // MARK: Enums

    public enum DukptDerivationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case aes128 = "AES_128"
        case aes192 = "AES_192"
        case aes256 = "AES_256"
        case tdes2Key = "TDES_2KEY"
        case tdes3Key = "TDES_3KEY"
        public var description: String { return self.rawValue }
    }

    public enum DukptEncryptionMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cbc = "CBC"
        case ecb = "ECB"
        public var description: String { return self.rawValue }
    }

    public enum DukptKeyVariant: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case bidirectional = "BIDIRECTIONAL"
        case request = "REQUEST"
        case response = "RESPONSE"
        public var description: String { return self.rawValue }
    }

    public enum EmvEncryptionMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cbc = "CBC"
        case ecb = "ECB"
        public var description: String { return self.rawValue }
    }

    public enum EmvMajorKeyDerivationMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case emvOptionA = "EMV_OPTION_A"
        case emvOptionB = "EMV_OPTION_B"
        public var description: String { return self.rawValue }
    }

    public enum EncryptionMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cbc = "CBC"
        case cfb = "CFB"
        case cfb1 = "CFB1"
        case cfb128 = "CFB128"
        case cfb64 = "CFB64"
        case cfb8 = "CFB8"
        case ecb = "ECB"
        case ofb = "OFB"
        public var description: String { return self.rawValue }
    }

    public enum KeyCheckValueAlgorithm: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ansiX924 = "ANSI_X9_24"
        case cmac = "CMAC"
        case hmac = "HMAC"
        case sha1 = "SHA_1"
        public var description: String { return self.rawValue }
    }

    public enum KeyDerivationFunction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ansiX963 = "ANSI_X963"
        case nistSp800 = "NIST_SP800"
        public var description: String { return self.rawValue }
    }

    public enum KeyDerivationHashAlgorithm: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case sha256 = "SHA_256"
        case sha384 = "SHA_384"
        case sha512 = "SHA_512"
        public var description: String { return self.rawValue }
    }

    public enum MacAlgorithm: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cmac = "CMAC"
        case hmac = "HMAC"
        case hmacSha224 = "HMAC_SHA224"
        case hmacSha256 = "HMAC_SHA256"
        case hmacSha384 = "HMAC_SHA384"
        case hmacSha512 = "HMAC_SHA512"
        case iso9797Algorithm1 = "ISO9797_ALGORITHM1"
        case iso9797Algorithm3 = "ISO9797_ALGORITHM3"
        public var description: String { return self.rawValue }
    }

    public enum MajorKeyDerivationMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case emvOptionA = "EMV_OPTION_A"
        case emvOptionB = "EMV_OPTION_B"
        public var description: String { return self.rawValue }
    }

    public enum PaddingType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case oaepSha1 = "OAEP_SHA1"
        case oaepSha256 = "OAEP_SHA256"
        case oaepSha512 = "OAEP_SHA512"
        case pkcs1 = "PKCS1"
        public var description: String { return self.rawValue }
    }

    public enum PinBlockFormatForEmvPinChange: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case isoFormat0 = "ISO_FORMAT_0"
        case isoFormat1 = "ISO_FORMAT_1"
        case isoFormat3 = "ISO_FORMAT_3"
        public var description: String { return self.rawValue }
    }

    public enum PinBlockFormatForPinData: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case isoFormat0 = "ISO_FORMAT_0"
        case isoFormat3 = "ISO_FORMAT_3"
        case isoFormat4 = "ISO_FORMAT_4"
        public var description: String { return self.rawValue }
    }

    public enum PinBlockLengthPosition: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case frontOfPinBlock = "FRONT_OF_PIN_BLOCK"
        case none = "NONE"
        public var description: String { return self.rawValue }
    }

    public enum PinBlockPaddingType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case isoIec78164 = "ISO_IEC_7816_4"
        case noPadding = "NO_PADDING"
        public var description: String { return self.rawValue }
    }

    public enum SessionKeyDerivationMode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case amex = "AMEX"
        case emv2000 = "EMV2000"
        case emvCommonSessionKey = "EMV_COMMON_SESSION_KEY"
        case mastercardSessionKey = "MASTERCARD_SESSION_KEY"
        case visa = "VISA"
        public var description: String { return self.rawValue }
    }

    public enum SymmetricKeyAlgorithm: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case aes128 = "AES_128"
        case aes192 = "AES_192"
        case aes256 = "AES_256"
        case hmacSha224 = "HMAC_SHA224"
        case hmacSha256 = "HMAC_SHA256"
        case hmacSha384 = "HMAC_SHA384"
        case hmacSha512 = "HMAC_SHA512"
        case tdes2Key = "TDES_2KEY"
        case tdes3Key = "TDES_3KEY"
        public var description: String { return self.rawValue }
    }

    public enum VerificationFailedReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case invalidAuthRequestCryptogram = "INVALID_AUTH_REQUEST_CRYPTOGRAM"
        case invalidMac = "INVALID_MAC"
        case invalidPin = "INVALID_PIN"
        case invalidValidationData = "INVALID_VALIDATION_DATA"
        public var description: String { return self.rawValue }
    }

    public enum CardGenerationAttributes: AWSEncodableShape, Sendable {
        case amexCardSecurityCodeVersion1(AmexCardSecurityCodeVersion1)
        /// Card data parameters that are required to generate a Card Security Code (CSC2) for an AMEX payment card.
        case amexCardSecurityCodeVersion2(AmexCardSecurityCodeVersion2)
        /// Card data parameters that are required to generate a cardholder verification value for the payment card.
        case cardHolderVerificationValue(CardHolderVerificationValue)
        /// Card data parameters that are required to generate Card Verification Value (CVV) for the payment card.
        case cardVerificationValue1(CardVerificationValue1)
        /// Card data parameters that are required to generate Card Verification Value (CVV2) for the payment card.
        case cardVerificationValue2(CardVerificationValue2)
        /// Card data parameters that are required to generate CDynamic Card Verification Code (dCVC) for the payment card.
        case dynamicCardVerificationCode(DynamicCardVerificationCode)
        /// Card data parameters that are required to generate CDynamic Card Verification Value (dCVV) for the payment card.
        case dynamicCardVerificationValue(DynamicCardVerificationValue)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .amexCardSecurityCodeVersion1(let value):
                try container.encode(value, forKey: .amexCardSecurityCodeVersion1)
            case .amexCardSecurityCodeVersion2(let value):
                try container.encode(value, forKey: .amexCardSecurityCodeVersion2)
            case .cardHolderVerificationValue(let value):
                try container.encode(value, forKey: .cardHolderVerificationValue)
            case .cardVerificationValue1(let value):
                try container.encode(value, forKey: .cardVerificationValue1)
            case .cardVerificationValue2(let value):
                try container.encode(value, forKey: .cardVerificationValue2)
            case .dynamicCardVerificationCode(let value):
                try container.encode(value, forKey: .dynamicCardVerificationCode)
            case .dynamicCardVerificationValue(let value):
                try container.encode(value, forKey: .dynamicCardVerificationValue)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .amexCardSecurityCodeVersion1(let value):
                try value.validate(name: "\(name).amexCardSecurityCodeVersion1")
            case .amexCardSecurityCodeVersion2(let value):
                try value.validate(name: "\(name).amexCardSecurityCodeVersion2")
            case .cardHolderVerificationValue(let value):
                try value.validate(name: "\(name).cardHolderVerificationValue")
            case .cardVerificationValue1(let value):
                try value.validate(name: "\(name).cardVerificationValue1")
            case .cardVerificationValue2(let value):
                try value.validate(name: "\(name).cardVerificationValue2")
            case .dynamicCardVerificationCode(let value):
                try value.validate(name: "\(name).dynamicCardVerificationCode")
            case .dynamicCardVerificationValue(let value):
                try value.validate(name: "\(name).dynamicCardVerificationValue")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case amexCardSecurityCodeVersion1 = "AmexCardSecurityCodeVersion1"
            case amexCardSecurityCodeVersion2 = "AmexCardSecurityCodeVersion2"
            case cardHolderVerificationValue = "CardHolderVerificationValue"
            case cardVerificationValue1 = "CardVerificationValue1"
            case cardVerificationValue2 = "CardVerificationValue2"
            case dynamicCardVerificationCode = "DynamicCardVerificationCode"
            case dynamicCardVerificationValue = "DynamicCardVerificationValue"
        }
    }

    public enum CardVerificationAttributes: AWSEncodableShape, Sendable {
        case amexCardSecurityCodeVersion1(AmexCardSecurityCodeVersion1)
        /// Card data parameters that are required to verify a Card Security Code (CSC2) for an AMEX payment card.
        case amexCardSecurityCodeVersion2(AmexCardSecurityCodeVersion2)
        /// Card data parameters that are required to verify a cardholder verification value for the payment card.
        case cardHolderVerificationValue(CardHolderVerificationValue)
        /// Card data parameters that are required to verify Card Verification Value (CVV) for the payment card.
        case cardVerificationValue1(CardVerificationValue1)
        /// Card data parameters that are required to verify Card Verification Value (CVV2) for the payment card.
        case cardVerificationValue2(CardVerificationValue2)
        /// Card data parameters that are required to verify CDynamic Card Verification Code (dCVC) for the payment card.
        case discoverDynamicCardVerificationCode(DiscoverDynamicCardVerificationCode)
        /// Card data parameters that are required to verify CDynamic Card Verification Code (dCVC) for the payment card.
        case dynamicCardVerificationCode(DynamicCardVerificationCode)
        /// Card data parameters that are required to verify CDynamic Card Verification Value (dCVV) for the payment card.
        case dynamicCardVerificationValue(DynamicCardVerificationValue)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .amexCardSecurityCodeVersion1(let value):
                try container.encode(value, forKey: .amexCardSecurityCodeVersion1)
            case .amexCardSecurityCodeVersion2(let value):
                try container.encode(value, forKey: .amexCardSecurityCodeVersion2)
            case .cardHolderVerificationValue(let value):
                try container.encode(value, forKey: .cardHolderVerificationValue)
            case .cardVerificationValue1(let value):
                try container.encode(value, forKey: .cardVerificationValue1)
            case .cardVerificationValue2(let value):
                try container.encode(value, forKey: .cardVerificationValue2)
            case .discoverDynamicCardVerificationCode(let value):
                try container.encode(value, forKey: .discoverDynamicCardVerificationCode)
            case .dynamicCardVerificationCode(let value):
                try container.encode(value, forKey: .dynamicCardVerificationCode)
            case .dynamicCardVerificationValue(let value):
                try container.encode(value, forKey: .dynamicCardVerificationValue)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .amexCardSecurityCodeVersion1(let value):
                try value.validate(name: "\(name).amexCardSecurityCodeVersion1")
            case .amexCardSecurityCodeVersion2(let value):
                try value.validate(name: "\(name).amexCardSecurityCodeVersion2")
            case .cardHolderVerificationValue(let value):
                try value.validate(name: "\(name).cardHolderVerificationValue")
            case .cardVerificationValue1(let value):
                try value.validate(name: "\(name).cardVerificationValue1")
            case .cardVerificationValue2(let value):
                try value.validate(name: "\(name).cardVerificationValue2")
            case .discoverDynamicCardVerificationCode(let value):
                try value.validate(name: "\(name).discoverDynamicCardVerificationCode")
            case .dynamicCardVerificationCode(let value):
                try value.validate(name: "\(name).dynamicCardVerificationCode")
            case .dynamicCardVerificationValue(let value):
                try value.validate(name: "\(name).dynamicCardVerificationValue")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case amexCardSecurityCodeVersion1 = "AmexCardSecurityCodeVersion1"
            case amexCardSecurityCodeVersion2 = "AmexCardSecurityCodeVersion2"
            case cardHolderVerificationValue = "CardHolderVerificationValue"
            case cardVerificationValue1 = "CardVerificationValue1"
            case cardVerificationValue2 = "CardVerificationValue2"
            case discoverDynamicCardVerificationCode = "DiscoverDynamicCardVerificationCode"
            case dynamicCardVerificationCode = "DynamicCardVerificationCode"
            case dynamicCardVerificationValue = "DynamicCardVerificationValue"
        }
    }

    public enum CryptogramAuthResponse: AWSEncodableShape, Sendable {
        /// Parameters that are required for ARPC response generation using method1 after ARQC verification is successful.
        case arpcMethod1(CryptogramVerificationArpcMethod1)
        /// Parameters that are required for ARPC response generation using method2 after ARQC verification is successful.
        case arpcMethod2(CryptogramVerificationArpcMethod2)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .arpcMethod1(let value):
                try container.encode(value, forKey: .arpcMethod1)
            case .arpcMethod2(let value):
                try container.encode(value, forKey: .arpcMethod2)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .arpcMethod1(let value):
                try value.validate(name: "\(name).arpcMethod1")
            case .arpcMethod2(let value):
                try value.validate(name: "\(name).arpcMethod2")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case arpcMethod1 = "ArpcMethod1"
            case arpcMethod2 = "ArpcMethod2"
        }
    }

    public enum DerivationMethodAttributes: AWSEncodableShape, Sendable {
        /// Parameters to derive the confidentiality and integrity keys for a payment card using Amex derivation method.
        case amex(AmexAttributes)
        /// Parameters to derive the confidentiality and integrity keys for a payment card using Emv2000 derivation method.
        case emv2000(Emv2000Attributes)
        /// Parameters to derive the confidentiality and integrity keys for a payment card using Emv common derivation method.
        case emvCommon(EmvCommonAttributes)
        /// Parameters to derive the confidentiality and integrity keys for a payment card using Mastercard derivation method.
        case mastercard(MasterCardAttributes)
        /// Parameters to derive the confidentiality and integrity keys for a a payment card using Visa derivation method.
        case visa(VisaAttributes)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .amex(let value):
                try container.encode(value, forKey: .amex)
            case .emv2000(let value):
                try container.encode(value, forKey: .emv2000)
            case .emvCommon(let value):
                try container.encode(value, forKey: .emvCommon)
            case .mastercard(let value):
                try container.encode(value, forKey: .mastercard)
            case .visa(let value):
                try container.encode(value, forKey: .visa)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .amex(let value):
                try value.validate(name: "\(name).amex")
            case .emv2000(let value):
                try value.validate(name: "\(name).emv2000")
            case .emvCommon(let value):
                try value.validate(name: "\(name).emvCommon")
            case .mastercard(let value):
                try value.validate(name: "\(name).mastercard")
            case .visa(let value):
                try value.validate(name: "\(name).visa")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case amex = "Amex"
            case emv2000 = "Emv2000"
            case emvCommon = "EmvCommon"
            case mastercard = "Mastercard"
            case visa = "Visa"
        }
    }

    public enum EncryptionDecryptionAttributes: AWSEncodableShape, Sendable {
        case asymmetric(AsymmetricEncryptionAttributes)
        case dukpt(DukptEncryptionAttributes)
        /// Parameters for plaintext encryption using EMV keys.
        case emv(EmvEncryptionAttributes)
        /// Parameters that are required to perform encryption and decryption using symmetric keys.
        case symmetric(SymmetricEncryptionAttributes)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .asymmetric(let value):
                try container.encode(value, forKey: .asymmetric)
            case .dukpt(let value):
                try container.encode(value, forKey: .dukpt)
            case .emv(let value):
                try container.encode(value, forKey: .emv)
            case .symmetric(let value):
                try container.encode(value, forKey: .symmetric)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .dukpt(let value):
                try value.validate(name: "\(name).dukpt")
            case .emv(let value):
                try value.validate(name: "\(name).emv")
            case .symmetric(let value):
                try value.validate(name: "\(name).symmetric")
            default:
                break
            }
        }

        private enum CodingKeys: String, CodingKey {
            case asymmetric = "Asymmetric"
            case dukpt = "Dukpt"
            case emv = "Emv"
            case symmetric = "Symmetric"
        }
    }

    public enum MacAttributes: AWSEncodableShape, Sendable {
        /// The encryption algorithm for MAC generation or verification.
        case algorithm(MacAlgorithm)
        /// Parameters that are required for MAC generation or verification using DUKPT CMAC algorithm.
        case dukptCmac(MacAlgorithmDukpt)
        /// Parameters that are required for MAC generation or verification using DUKPT ISO 9797 algorithm1.
        case dukptIso9797Algorithm1(MacAlgorithmDukpt)
        /// Parameters that are required for MAC generation or verification using DUKPT ISO 9797 algorithm3.
        case dukptIso9797Algorithm3(MacAlgorithmDukpt)
        /// Parameters that are required for MAC generation or verification using EMV MAC algorithm.
        case emvMac(MacAlgorithmEmv)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .algorithm(let value):
                try container.encode(value, forKey: .algorithm)
            case .dukptCmac(let value):
                try container.encode(value, forKey: .dukptCmac)
            case .dukptIso9797Algorithm1(let value):
                try container.encode(value, forKey: .dukptIso9797Algorithm1)
            case .dukptIso9797Algorithm3(let value):
                try container.encode(value, forKey: .dukptIso9797Algorithm3)
            case .emvMac(let value):
                try container.encode(value, forKey: .emvMac)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .dukptCmac(let value):
                try value.validate(name: "\(name).dukptCmac")
            case .dukptIso9797Algorithm1(let value):
                try value.validate(name: "\(name).dukptIso9797Algorithm1")
            case .dukptIso9797Algorithm3(let value):
                try value.validate(name: "\(name).dukptIso9797Algorithm3")
            case .emvMac(let value):
                try value.validate(name: "\(name).emvMac")
            default:
                break
            }
        }

        private enum CodingKeys: String, CodingKey {
            case algorithm = "Algorithm"
            case dukptCmac = "DukptCmac"
            case dukptIso9797Algorithm1 = "DukptIso9797Algorithm1"
            case dukptIso9797Algorithm3 = "DukptIso9797Algorithm3"
            case emvMac = "EmvMac"
        }
    }

    public enum PinData: AWSDecodableShape, Sendable {
        /// The PIN offset value.
        case pinOffset(String)
        /// The unique data to identify a cardholder. In most cases, this is the same as cardholder's Primary Account Number (PAN). If a value is not provided, it defaults to PAN.
        case verificationValue(String)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .pinOffset:
                let value = try container.decode(String.self, forKey: .pinOffset)
                self = .pinOffset(value)
            case .verificationValue:
                let value = try container.decode(String.self, forKey: .verificationValue)
                self = .verificationValue(value)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case pinOffset = "PinOffset"
            case verificationValue = "VerificationValue"
        }
    }

    public enum PinGenerationAttributes: AWSEncodableShape, Sendable {
        /// Parameters that are required to generate or verify Ibm3624 natural PIN.
        case ibm3624NaturalPin(Ibm3624NaturalPin)
        /// Parameters that are required to generate or verify Ibm3624 PIN from offset PIN.
        case ibm3624PinFromOffset(Ibm3624PinFromOffset)
        /// Parameters that are required to generate or verify Ibm3624 PIN offset PIN.
        case ibm3624PinOffset(Ibm3624PinOffset)
        /// Parameters that are required to generate or verify Ibm3624 random PIN.
        case ibm3624RandomPin(Ibm3624RandomPin)
        /// Parameters that are required to generate or verify Visa PIN.
        case visaPin(VisaPin)
        /// Parameters that are required to generate or verify Visa PIN Verification Value (PVV).
        case visaPinVerificationValue(VisaPinVerificationValue)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .ibm3624NaturalPin(let value):
                try container.encode(value, forKey: .ibm3624NaturalPin)
            case .ibm3624PinFromOffset(let value):
                try container.encode(value, forKey: .ibm3624PinFromOffset)
            case .ibm3624PinOffset(let value):
                try container.encode(value, forKey: .ibm3624PinOffset)
            case .ibm3624RandomPin(let value):
                try container.encode(value, forKey: .ibm3624RandomPin)
            case .visaPin(let value):
                try container.encode(value, forKey: .visaPin)
            case .visaPinVerificationValue(let value):
                try container.encode(value, forKey: .visaPinVerificationValue)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .ibm3624NaturalPin(let value):
                try value.validate(name: "\(name).ibm3624NaturalPin")
            case .ibm3624PinFromOffset(let value):
                try value.validate(name: "\(name).ibm3624PinFromOffset")
            case .ibm3624PinOffset(let value):
                try value.validate(name: "\(name).ibm3624PinOffset")
            case .ibm3624RandomPin(let value):
                try value.validate(name: "\(name).ibm3624RandomPin")
            case .visaPin(let value):
                try value.validate(name: "\(name).visaPin")
            case .visaPinVerificationValue(let value):
                try value.validate(name: "\(name).visaPinVerificationValue")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case ibm3624NaturalPin = "Ibm3624NaturalPin"
            case ibm3624PinFromOffset = "Ibm3624PinFromOffset"
            case ibm3624PinOffset = "Ibm3624PinOffset"
            case ibm3624RandomPin = "Ibm3624RandomPin"
            case visaPin = "VisaPin"
            case visaPinVerificationValue = "VisaPinVerificationValue"
        }
    }

    public enum PinVerificationAttributes: AWSEncodableShape, Sendable {
        /// Parameters that are required to generate or verify Ibm3624 PIN.
        case ibm3624Pin(Ibm3624PinVerification)
        /// Parameters that are required to generate or verify Visa PIN.
        case visaPin(VisaPinVerification)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .ibm3624Pin(let value):
                try container.encode(value, forKey: .ibm3624Pin)
            case .visaPin(let value):
                try container.encode(value, forKey: .visaPin)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .ibm3624Pin(let value):
                try value.validate(name: "\(name).ibm3624Pin")
            case .visaPin(let value):
                try value.validate(name: "\(name).visaPin")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case ibm3624Pin = "Ibm3624Pin"
            case visaPin = "VisaPin"
        }
    }

    public enum ReEncryptionAttributes: AWSEncodableShape, Sendable {
        case dukpt(DukptEncryptionAttributes)
        /// Parameters that are required to encrypt data using symmetric keys.
        case symmetric(SymmetricEncryptionAttributes)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .dukpt(let value):
                try container.encode(value, forKey: .dukpt)
            case .symmetric(let value):
                try container.encode(value, forKey: .symmetric)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .dukpt(let value):
                try value.validate(name: "\(name).dukpt")
            case .symmetric(let value):
                try value.validate(name: "\(name).symmetric")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case dukpt = "Dukpt"
            case symmetric = "Symmetric"
        }
    }

    public enum SessionKeyDerivation: AWSEncodableShape, Sendable {
        /// Parameters to derive session key for an Amex payment card for ARQC verification.
        case amex(SessionKeyAmex)
        /// Parameters to derive session key for an Emv2000 payment card for ARQC verification.
        case emv2000(SessionKeyEmv2000)
        /// Parameters to derive session key for an Emv common payment card for ARQC verification.
        case emvCommon(SessionKeyEmvCommon)
        /// Parameters to derive session key for a Mastercard payment card for ARQC verification.
        case mastercard(SessionKeyMastercard)
        /// Parameters to derive session key for a Visa payment cardfor ARQC verification.
        case visa(SessionKeyVisa)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .amex(let value):
                try container.encode(value, forKey: .amex)
            case .emv2000(let value):
                try container.encode(value, forKey: .emv2000)
            case .emvCommon(let value):
                try container.encode(value, forKey: .emvCommon)
            case .mastercard(let value):
                try container.encode(value, forKey: .mastercard)
            case .visa(let value):
                try container.encode(value, forKey: .visa)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .amex(let value):
                try value.validate(name: "\(name).amex")
            case .emv2000(let value):
                try value.validate(name: "\(name).emv2000")
            case .emvCommon(let value):
                try value.validate(name: "\(name).emvCommon")
            case .mastercard(let value):
                try value.validate(name: "\(name).mastercard")
            case .visa(let value):
                try value.validate(name: "\(name).visa")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case amex = "Amex"
            case emv2000 = "Emv2000"
            case emvCommon = "EmvCommon"
            case mastercard = "Mastercard"
            case visa = "Visa"
        }
    }

    public enum SessionKeyDerivationValue: AWSEncodableShape, Sendable {
        /// The cryptogram provided by the terminal during transaction processing.
        case applicationCryptogram(String)
        /// The transaction counter that is provided by the terminal during transaction processing.
        case applicationTransactionCounter(String)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .applicationCryptogram(let value):
                try container.encode(value, forKey: .applicationCryptogram)
            case .applicationTransactionCounter(let value):
                try container.encode(value, forKey: .applicationTransactionCounter)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .applicationCryptogram(let value):
                try self.validate(value, name: "applicationCryptogram", parent: name, max: 16)
                try self.validate(value, name: "applicationCryptogram", parent: name, min: 16)
                try self.validate(value, name: "applicationCryptogram", parent: name, pattern: "^[0-9a-fA-F]+$")
            case .applicationTransactionCounter(let value):
                try self.validate(value, name: "applicationTransactionCounter", parent: name, max: 4)
                try self.validate(value, name: "applicationTransactionCounter", parent: name, min: 4)
                try self.validate(value, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case applicationCryptogram = "ApplicationCryptogram"
            case applicationTransactionCounter = "ApplicationTransactionCounter"
        }
    }

    public enum TranslationIsoFormats: AWSEncodableShape, Sendable {
        /// Parameters that are required for ISO9564 PIN format 0 tranlation.
        case isoFormat0(TranslationPinDataIsoFormat034)
        /// Parameters that are required for ISO9564 PIN format 1 tranlation.
        case isoFormat1(TranslationPinDataIsoFormat1)
        /// Parameters that are required for ISO9564 PIN format 3 tranlation.
        case isoFormat3(TranslationPinDataIsoFormat034)
        /// Parameters that are required for ISO9564 PIN format 4 tranlation.
        case isoFormat4(TranslationPinDataIsoFormat034)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .isoFormat0(let value):
                try container.encode(value, forKey: .isoFormat0)
            case .isoFormat1(let value):
                try container.encode(value, forKey: .isoFormat1)
            case .isoFormat3(let value):
                try container.encode(value, forKey: .isoFormat3)
            case .isoFormat4(let value):
                try container.encode(value, forKey: .isoFormat4)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .isoFormat0(let value):
                try value.validate(name: "\(name).isoFormat0")
            case .isoFormat3(let value):
                try value.validate(name: "\(name).isoFormat3")
            case .isoFormat4(let value):
                try value.validate(name: "\(name).isoFormat4")
            default:
                break
            }
        }

        private enum CodingKeys: String, CodingKey {
            case isoFormat0 = "IsoFormat0"
            case isoFormat1 = "IsoFormat1"
            case isoFormat3 = "IsoFormat3"
            case isoFormat4 = "IsoFormat4"
        }
    }

    public enum WrappedKeyMaterial: AWSEncodableShape, Sendable {
        /// The parameter information for deriving a ECDH shared key.
        case diffieHellmanSymmetricKey(EcdhDerivationAttributes)
        /// The TR-31 wrapped key block.
        case tr31KeyBlock(String)

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .diffieHellmanSymmetricKey(let value):
                try container.encode(value, forKey: .diffieHellmanSymmetricKey)
            case .tr31KeyBlock(let value):
                try container.encode(value, forKey: .tr31KeyBlock)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .diffieHellmanSymmetricKey(let value):
                try value.validate(name: "\(name).diffieHellmanSymmetricKey")
            case .tr31KeyBlock(let value):
                try self.validate(value, name: "tr31KeyBlock", parent: name, max: 9984)
                try self.validate(value, name: "tr31KeyBlock", parent: name, min: 56)
                try self.validate(value, name: "tr31KeyBlock", parent: name, pattern: "^[0-9A-Z]+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case diffieHellmanSymmetricKey = "DiffieHellmanSymmetricKey"
            case tr31KeyBlock = "Tr31KeyBlock"
        }
    }

    // MARK: Shapes

    public struct AmexAttributes: AWSEncodableShape {
        /// The transaction counter of the current transaction that is provided by the terminal during transaction processing.
        public let applicationTransactionCounter: String
        /// The keyArn of the issuer master key for cryptogram (IMK-AC) for the payment card.
        public let authorizationRequestKeyIdentifier: String
        /// The encrypted pinblock of the old pin stored on the chip card.
        public let currentPinAttributes: CurrentPinAttributes?
        /// The method to use when deriving the master key for a payment card using Amex derivation.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN). Typically 00 is used, if no value is provided by the terminal.
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, authorizationRequestKeyIdentifier: String, currentPinAttributes: CurrentPinAttributes? = nil, majorKeyDerivationMode: MajorKeyDerivationMode, panSequenceNumber: String, primaryAccountNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.authorizationRequestKeyIdentifier = authorizationRequestKeyIdentifier
            self.currentPinAttributes = currentPinAttributes
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.authorizationRequestKeyIdentifier, name: "authorizationRequestKeyIdentifier", parent: name, max: 322)
            try self.validate(self.authorizationRequestKeyIdentifier, name: "authorizationRequestKeyIdentifier", parent: name, min: 7)
            try self.validate(self.authorizationRequestKeyIdentifier, name: "authorizationRequestKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.currentPinAttributes?.validate(name: "\(name).currentPinAttributes")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case authorizationRequestKeyIdentifier = "AuthorizationRequestKeyIdentifier"
            case currentPinAttributes = "CurrentPinAttributes"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct AmexCardSecurityCodeVersion1: AWSEncodableShape {
        /// The expiry date of a payment card.
        public let cardExpiryDate: String

        @inlinable
        public init(cardExpiryDate: String) {
            self.cardExpiryDate = cardExpiryDate
        }

        public func validate(name: String) throws {
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, max: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, min: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case cardExpiryDate = "CardExpiryDate"
        }
    }

    public struct AmexCardSecurityCodeVersion2: AWSEncodableShape {
        /// The expiry date of a payment card.
        public let cardExpiryDate: String
        /// The service code of the AMEX payment card. This is different from the Card Security Code (CSC).
        public let serviceCode: String

        @inlinable
        public init(cardExpiryDate: String, serviceCode: String) {
            self.cardExpiryDate = cardExpiryDate
            self.serviceCode = serviceCode
        }

        public func validate(name: String) throws {
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, max: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, min: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, max: 3)
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, min: 3)
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case cardExpiryDate = "CardExpiryDate"
            case serviceCode = "ServiceCode"
        }
    }

    public struct AsymmetricEncryptionAttributes: AWSEncodableShape {
        /// The padding to be included with the data.
        public let paddingType: PaddingType?

        @inlinable
        public init(paddingType: PaddingType? = nil) {
            self.paddingType = paddingType
        }

        private enum CodingKeys: String, CodingKey {
            case paddingType = "PaddingType"
        }
    }

    public struct CardHolderVerificationValue: AWSEncodableShape {
        /// The transaction counter value that comes from a point of sale terminal.
        public let applicationTransactionCounter: String
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// A random number generated by the issuer.
        public let unpredictableNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, panSequenceNumber: String, unpredictableNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.panSequenceNumber = panSequenceNumber
            self.unpredictableNumber = unpredictableNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 2)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, max: 8)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, min: 2)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case panSequenceNumber = "PanSequenceNumber"
            case unpredictableNumber = "UnpredictableNumber"
        }
    }

    public struct CardVerificationValue1: AWSEncodableShape {
        /// The expiry date of a payment card.
        public let cardExpiryDate: String
        /// The service code of the payment card. This is different from Card Security Code (CSC).
        public let serviceCode: String

        @inlinable
        public init(cardExpiryDate: String, serviceCode: String) {
            self.cardExpiryDate = cardExpiryDate
            self.serviceCode = serviceCode
        }

        public func validate(name: String) throws {
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, max: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, min: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, max: 3)
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, min: 3)
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case cardExpiryDate = "CardExpiryDate"
            case serviceCode = "ServiceCode"
        }
    }

    public struct CardVerificationValue2: AWSEncodableShape {
        /// The expiry date of a payment card.
        public let cardExpiryDate: String

        @inlinable
        public init(cardExpiryDate: String) {
            self.cardExpiryDate = cardExpiryDate
        }

        public func validate(name: String) throws {
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, max: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, min: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case cardExpiryDate = "CardExpiryDate"
        }
    }

    public struct CryptogramVerificationArpcMethod1: AWSEncodableShape {
        /// The auth code used to calculate APRC after ARQC verification is successful. This is the same auth code used for ARQC generation outside of Amazon Web Services Payment Cryptography.
        public let authResponseCode: String

        @inlinable
        public init(authResponseCode: String) {
            self.authResponseCode = authResponseCode
        }

        public func validate(name: String) throws {
            try self.validate(self.authResponseCode, name: "authResponseCode", parent: name, max: 4)
            try self.validate(self.authResponseCode, name: "authResponseCode", parent: name, min: 4)
            try self.validate(self.authResponseCode, name: "authResponseCode", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case authResponseCode = "AuthResponseCode"
        }
    }

    public struct CryptogramVerificationArpcMethod2: AWSEncodableShape {
        /// The data indicating whether the issuer approves or declines an online transaction using an EMV chip card.
        public let cardStatusUpdate: String
        /// The proprietary authentication data used by issuer for communication during online transaction using an EMV chip card.
        public let proprietaryAuthenticationData: String?

        @inlinable
        public init(cardStatusUpdate: String, proprietaryAuthenticationData: String? = nil) {
            self.cardStatusUpdate = cardStatusUpdate
            self.proprietaryAuthenticationData = proprietaryAuthenticationData
        }

        public func validate(name: String) throws {
            try self.validate(self.cardStatusUpdate, name: "cardStatusUpdate", parent: name, max: 8)
            try self.validate(self.cardStatusUpdate, name: "cardStatusUpdate", parent: name, min: 8)
            try self.validate(self.cardStatusUpdate, name: "cardStatusUpdate", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.proprietaryAuthenticationData, name: "proprietaryAuthenticationData", parent: name, max: 16)
            try self.validate(self.proprietaryAuthenticationData, name: "proprietaryAuthenticationData", parent: name, min: 1)
            try self.validate(self.proprietaryAuthenticationData, name: "proprietaryAuthenticationData", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case cardStatusUpdate = "CardStatusUpdate"
            case proprietaryAuthenticationData = "ProprietaryAuthenticationData"
        }
    }

    public struct CurrentPinAttributes: AWSEncodableShape {
        /// The encrypted pinblock of the current pin stored on the chip card.
        public let currentEncryptedPinBlock: String
        /// The keyArn of the current PIN PEK.
        public let currentPinPekIdentifier: String

        @inlinable
        public init(currentEncryptedPinBlock: String, currentPinPekIdentifier: String) {
            self.currentEncryptedPinBlock = currentEncryptedPinBlock
            self.currentPinPekIdentifier = currentPinPekIdentifier
        }

        public func validate(name: String) throws {
            try self.validate(self.currentEncryptedPinBlock, name: "currentEncryptedPinBlock", parent: name, max: 16)
            try self.validate(self.currentEncryptedPinBlock, name: "currentEncryptedPinBlock", parent: name, min: 16)
            try self.validate(self.currentEncryptedPinBlock, name: "currentEncryptedPinBlock", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.currentPinPekIdentifier, name: "currentPinPekIdentifier", parent: name, max: 322)
            try self.validate(self.currentPinPekIdentifier, name: "currentPinPekIdentifier", parent: name, min: 7)
            try self.validate(self.currentPinPekIdentifier, name: "currentPinPekIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case currentEncryptedPinBlock = "CurrentEncryptedPinBlock"
            case currentPinPekIdentifier = "CurrentPinPekIdentifier"
        }
    }

    public struct DecryptDataInput: AWSEncodableShape {
        /// The ciphertext to decrypt.
        public let cipherText: String
        /// The encryption key type and attributes for ciphertext decryption.
        public let decryptionAttributes: EncryptionDecryptionAttributes
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses for ciphertext decryption. When a WrappedKeyBlock is provided, this value will be the identifier to the key wrapping key. Otherwise, it is the key identifier used to perform the operation.
        public let keyIdentifier: String
        /// The WrappedKeyBlock containing the encryption key for ciphertext decryption.
        public let wrappedKey: WrappedKey?

        @inlinable
        public init(cipherText: String, decryptionAttributes: EncryptionDecryptionAttributes, keyIdentifier: String, wrappedKey: WrappedKey? = nil) {
            self.cipherText = cipherText
            self.decryptionAttributes = decryptionAttributes
            self.keyIdentifier = keyIdentifier
            self.wrappedKey = wrappedKey
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.cipherText, forKey: .cipherText)
            try container.encode(self.decryptionAttributes, forKey: .decryptionAttributes)
            request.encodePath(self.keyIdentifier, key: "KeyIdentifier")
            try container.encodeIfPresent(self.wrappedKey, forKey: .wrappedKey)
        }

        public func validate(name: String) throws {
            try self.validate(self.cipherText, name: "cipherText", parent: name, max: 4224)
            try self.validate(self.cipherText, name: "cipherText", parent: name, min: 2)
            try self.validate(self.cipherText, name: "cipherText", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.decryptionAttributes.validate(name: "\(name).decryptionAttributes")
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.wrappedKey?.validate(name: "\(name).wrappedKey")
        }

        private enum CodingKeys: String, CodingKey {
            case cipherText = "CipherText"
            case decryptionAttributes = "DecryptionAttributes"
            case wrappedKey = "WrappedKey"
        }
    }

    public struct DecryptDataOutput: AWSDecodableShape {
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses for ciphertext decryption.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String
        /// The decrypted plaintext data in hexBinary format.
        public let plainText: String

        @inlinable
        public init(keyArn: String, keyCheckValue: String, plainText: String) {
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
            self.plainText = plainText
        }

        private enum CodingKeys: String, CodingKey {
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
            case plainText = "PlainText"
        }
    }

    public struct DiscoverDynamicCardVerificationCode: AWSEncodableShape {
        /// The transaction counter value that comes from the terminal.
        public let applicationTransactionCounter: String
        /// The expiry date of a payment card.
        public let cardExpiryDate: String
        /// A random number that is generated by the issuer.
        public let unpredictableNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, cardExpiryDate: String, unpredictableNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.cardExpiryDate = cardExpiryDate
            self.unpredictableNumber = unpredictableNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 2)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, max: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, min: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, max: 8)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, min: 2)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case cardExpiryDate = "CardExpiryDate"
            case unpredictableNumber = "UnpredictableNumber"
        }
    }

    public struct DukptAttributes: AWSEncodableShape {
        /// The key type derived using DUKPT from a Base Derivation Key (BDK) and Key Serial Number (KSN). This must be less than or equal to the strength of the BDK. For example, you can't use AES_128 as a derivation type for a BDK of AES_128 or TDES_2KEY.
        public let dukptDerivationType: DukptDerivationType
        /// The unique identifier known as Key Serial Number (KSN) that comes from an encrypting device using DUKPT encryption method. The KSN is derived from the encrypting device unique identifier and an internal transaction counter.
        public let keySerialNumber: String

        @inlinable
        public init(dukptDerivationType: DukptDerivationType, keySerialNumber: String) {
            self.dukptDerivationType = dukptDerivationType
            self.keySerialNumber = keySerialNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, max: 24)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, min: 16)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{20}|[0-9a-fA-F]{24})$")
        }

        private enum CodingKeys: String, CodingKey {
            case dukptDerivationType = "DukptDerivationType"
            case keySerialNumber = "KeySerialNumber"
        }
    }

    public struct DukptDerivationAttributes: AWSEncodableShape {
        /// The key type derived using DUKPT from a Base Derivation Key (BDK) and Key Serial Number (KSN). This must be less than or equal to the strength of the BDK. For example, you can't use AES_128 as a derivation type for a BDK of AES_128 or TDES_2KEY
        public let dukptKeyDerivationType: DukptDerivationType?
        /// The type of use of DUKPT, which can be for incoming data decryption, outgoing data encryption, or both.
        public let dukptKeyVariant: DukptKeyVariant?
        /// The unique identifier known as Key Serial Number (KSN) that comes from an encrypting device using DUKPT encryption method. The KSN is derived from the encrypting device unique identifier and an internal transaction counter.
        public let keySerialNumber: String

        @inlinable
        public init(dukptKeyDerivationType: DukptDerivationType? = nil, dukptKeyVariant: DukptKeyVariant? = nil, keySerialNumber: String) {
            self.dukptKeyDerivationType = dukptKeyDerivationType
            self.dukptKeyVariant = dukptKeyVariant
            self.keySerialNumber = keySerialNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, max: 24)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, min: 16)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{20}|[0-9a-fA-F]{24})$")
        }

        private enum CodingKeys: String, CodingKey {
            case dukptKeyDerivationType = "DukptKeyDerivationType"
            case dukptKeyVariant = "DukptKeyVariant"
            case keySerialNumber = "KeySerialNumber"
        }
    }

    public struct DukptEncryptionAttributes: AWSEncodableShape {
        /// The key type encrypted using DUKPT from a Base Derivation Key (BDK) and Key Serial Number (KSN). This must be less than or equal to the strength of the BDK. For example, you can't use AES_128 as a derivation type for a BDK of AES_128 or TDES_2KEY
        public let dukptKeyDerivationType: DukptDerivationType?
        /// The type of use of DUKPT, which can be incoming data decryption, outgoing data encryption, or both.
        public let dukptKeyVariant: DukptKeyVariant?
        /// An input used to provide the intial state. If no value is provided, Amazon Web Services Payment Cryptography defaults it to zero.
        public let initializationVector: String?
        /// The unique identifier known as Key Serial Number (KSN) that comes from an encrypting device using DUKPT encryption method. The KSN is derived from the encrypting device unique identifier and an internal transaction counter.
        public let keySerialNumber: String
        /// The block cipher method to use for encryption. The default is CBC.
        public let mode: DukptEncryptionMode?

        @inlinable
        public init(dukptKeyDerivationType: DukptDerivationType? = nil, dukptKeyVariant: DukptKeyVariant? = nil, initializationVector: String? = nil, keySerialNumber: String, mode: DukptEncryptionMode? = nil) {
            self.dukptKeyDerivationType = dukptKeyDerivationType
            self.dukptKeyVariant = dukptKeyVariant
            self.initializationVector = initializationVector
            self.keySerialNumber = keySerialNumber
            self.mode = mode
        }

        public func validate(name: String) throws {
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, max: 32)
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, min: 16)
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{32})$")
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, max: 24)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, min: 16)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{20}|[0-9a-fA-F]{24})$")
        }

        private enum CodingKeys: String, CodingKey {
            case dukptKeyDerivationType = "DukptKeyDerivationType"
            case dukptKeyVariant = "DukptKeyVariant"
            case initializationVector = "InitializationVector"
            case keySerialNumber = "KeySerialNumber"
            case mode = "Mode"
        }
    }

    public struct DynamicCardVerificationCode: AWSEncodableShape {
        /// The transaction counter value that comes from the terminal.
        public let applicationTransactionCounter: String
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The data on the two tracks of magnetic cards used for financial transactions. This includes the cardholder name, PAN, expiration date, bank ID (BIN) and several other numbers the issuing bank uses to validate the data received.
        public let trackData: String
        /// A random number generated by the issuer.
        public let unpredictableNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, panSequenceNumber: String, trackData: String, unpredictableNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.panSequenceNumber = panSequenceNumber
            self.trackData = trackData
            self.unpredictableNumber = unpredictableNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 2)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.trackData, name: "trackData", parent: name, max: 160)
            try self.validate(self.trackData, name: "trackData", parent: name, min: 2)
            try self.validate(self.trackData, name: "trackData", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, max: 8)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, min: 2)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case panSequenceNumber = "PanSequenceNumber"
            case trackData = "TrackData"
            case unpredictableNumber = "UnpredictableNumber"
        }
    }

    public struct DynamicCardVerificationValue: AWSEncodableShape {
        /// The transaction counter value that comes from the terminal.
        public let applicationTransactionCounter: String
        /// The expiry date of a payment card.
        public let cardExpiryDate: String
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The service code of the payment card. This is different from Card Security Code (CSC).
        public let serviceCode: String

        @inlinable
        public init(applicationTransactionCounter: String, cardExpiryDate: String, panSequenceNumber: String, serviceCode: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.cardExpiryDate = cardExpiryDate
            self.panSequenceNumber = panSequenceNumber
            self.serviceCode = serviceCode
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 2)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, max: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, min: 4)
            try self.validate(self.cardExpiryDate, name: "cardExpiryDate", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, max: 3)
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, min: 3)
            try self.validate(self.serviceCode, name: "serviceCode", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case cardExpiryDate = "CardExpiryDate"
            case panSequenceNumber = "PanSequenceNumber"
            case serviceCode = "ServiceCode"
        }
    }

    public struct EcdhDerivationAttributes: AWSEncodableShape {
        /// The keyArn of the certificate that signed the client's PublicKeyCertificate.
        public let certificateAuthorityPublicKeyIdentifier: String
        /// The key algorithm of the derived ECDH key.
        public let keyAlgorithm: SymmetricKeyAlgorithm
        /// The key derivation function to use for deriving a key using ECDH.
        public let keyDerivationFunction: KeyDerivationFunction
        /// The hash type to use for deriving a key using ECDH.
        public let keyDerivationHashAlgorithm: KeyDerivationHashAlgorithm
        /// The client's public key certificate in PEM format (base64 encoded) to use for ECDH key derivation.
        public let publicKeyCertificate: String
        /// A byte string containing information that binds the ECDH derived key to the two parties involved or to the context of the key. It may include details like identities of the two parties deriving the key, context of the operation, session IDs, and optionally a nonce. It must not contain zero bytes, and re-using shared information for multiple ECDH key derivations is not recommended.
        public let sharedInformation: String

        @inlinable
        public init(certificateAuthorityPublicKeyIdentifier: String, keyAlgorithm: SymmetricKeyAlgorithm, keyDerivationFunction: KeyDerivationFunction, keyDerivationHashAlgorithm: KeyDerivationHashAlgorithm, publicKeyCertificate: String, sharedInformation: String) {
            self.certificateAuthorityPublicKeyIdentifier = certificateAuthorityPublicKeyIdentifier
            self.keyAlgorithm = keyAlgorithm
            self.keyDerivationFunction = keyDerivationFunction
            self.keyDerivationHashAlgorithm = keyDerivationHashAlgorithm
            self.publicKeyCertificate = publicKeyCertificate
            self.sharedInformation = sharedInformation
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateAuthorityPublicKeyIdentifier, name: "certificateAuthorityPublicKeyIdentifier", parent: name, max: 322)
            try self.validate(self.certificateAuthorityPublicKeyIdentifier, name: "certificateAuthorityPublicKeyIdentifier", parent: name, min: 7)
            try self.validate(self.certificateAuthorityPublicKeyIdentifier, name: "certificateAuthorityPublicKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.publicKeyCertificate, name: "publicKeyCertificate", parent: name, max: 32768)
            try self.validate(self.publicKeyCertificate, name: "publicKeyCertificate", parent: name, min: 1)
            try self.validate(self.publicKeyCertificate, name: "publicKeyCertificate", parent: name, pattern: "^[^\\[;\\]<>]+$")
            try self.validate(self.sharedInformation, name: "sharedInformation", parent: name, max: 2048)
            try self.validate(self.sharedInformation, name: "sharedInformation", parent: name, min: 2)
            try self.validate(self.sharedInformation, name: "sharedInformation", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateAuthorityPublicKeyIdentifier = "CertificateAuthorityPublicKeyIdentifier"
            case keyAlgorithm = "KeyAlgorithm"
            case keyDerivationFunction = "KeyDerivationFunction"
            case keyDerivationHashAlgorithm = "KeyDerivationHashAlgorithm"
            case publicKeyCertificate = "PublicKeyCertificate"
            case sharedInformation = "SharedInformation"
        }
    }

    public struct Emv2000Attributes: AWSEncodableShape {
        /// The transaction counter of the current transaction that is provided by the terminal during transaction processing.
        public let applicationTransactionCounter: String
        /// The method to use when deriving the master key for the payment card.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN). Typically 00 is used, if no value is provided by the terminal.
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, majorKeyDerivationMode: MajorKeyDerivationMode, panSequenceNumber: String, primaryAccountNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct EmvCommonAttributes: AWSEncodableShape {
        /// The application cryptogram for the current transaction that is provided by the terminal during transaction processing.
        public let applicationCryptogram: String
        /// The method to use when deriving the master key for the payment card.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// The block cipher method to use for encryption.
        public let mode: EmvEncryptionMode
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN). Typically 00 is used, if no value is provided by the terminal.
        public let panSequenceNumber: String
        /// Specifies if PIN block length should be added to front of the pin block.  If value is set to FRONT_OF_PIN_BLOCK, then PIN block padding type should be ISO_IEC_7816_4.
        public let pinBlockLengthPosition: PinBlockLengthPosition
        /// The padding to be added to the PIN block prior to encryption. Padding type should be ISO_IEC_7816_4, if PinBlockLengthPosition is set to FRONT_OF_PIN_BLOCK. No padding is required, if PinBlockLengthPosition is set to NONE.
        public let pinBlockPaddingType: PinBlockPaddingType
        /// The Primary Account Number (PAN) of the cardholder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationCryptogram: String, majorKeyDerivationMode: MajorKeyDerivationMode, mode: EmvEncryptionMode, panSequenceNumber: String, pinBlockLengthPosition: PinBlockLengthPosition, pinBlockPaddingType: PinBlockPaddingType, primaryAccountNumber: String) {
            self.applicationCryptogram = applicationCryptogram
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.mode = mode
            self.panSequenceNumber = panSequenceNumber
            self.pinBlockLengthPosition = pinBlockLengthPosition
            self.pinBlockPaddingType = pinBlockPaddingType
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationCryptogram, name: "applicationCryptogram", parent: name, max: 16)
            try self.validate(self.applicationCryptogram, name: "applicationCryptogram", parent: name, min: 16)
            try self.validate(self.applicationCryptogram, name: "applicationCryptogram", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationCryptogram = "ApplicationCryptogram"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case mode = "Mode"
            case panSequenceNumber = "PanSequenceNumber"
            case pinBlockLengthPosition = "PinBlockLengthPosition"
            case pinBlockPaddingType = "PinBlockPaddingType"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct EmvEncryptionAttributes: AWSEncodableShape {
        /// An input used to provide the intial state. If no value is provided, Amazon Web Services Payment Cryptography defaults it to zero.
        public let initializationVector: String?
        /// The EMV derivation mode to use for ICC master key derivation as per EMV version 4.3 book 2.
        public let majorKeyDerivationMode: EmvMajorKeyDerivationMode
        /// The block cipher method to use for encryption.
        public let mode: EmvEncryptionMode?
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN). Typically 00 is used, if no value is provided by the terminal.
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN), a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String
        /// The derivation value used to derive the ICC session key. It is typically the application transaction counter value padded with zeros or previous ARQC value padded with zeros as per EMV version 4.3 book 2.
        public let sessionDerivationData: String

        @inlinable
        public init(initializationVector: String? = nil, majorKeyDerivationMode: EmvMajorKeyDerivationMode, mode: EmvEncryptionMode? = nil, panSequenceNumber: String, primaryAccountNumber: String, sessionDerivationData: String) {
            self.initializationVector = initializationVector
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.mode = mode
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
            self.sessionDerivationData = sessionDerivationData
        }

        public func validate(name: String) throws {
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, max: 32)
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, min: 16)
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{32})$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.sessionDerivationData, name: "sessionDerivationData", parent: name, max: 16)
            try self.validate(self.sessionDerivationData, name: "sessionDerivationData", parent: name, min: 16)
            try self.validate(self.sessionDerivationData, name: "sessionDerivationData", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case initializationVector = "InitializationVector"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case mode = "Mode"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
            case sessionDerivationData = "SessionDerivationData"
        }
    }

    public struct EncryptDataInput: AWSEncodableShape {
        /// The encryption key type and attributes for plaintext encryption.
        public let encryptionAttributes: EncryptionDecryptionAttributes
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses for plaintext encryption. When a WrappedKeyBlock is provided, this value will be the identifier to the key wrapping key. Otherwise, it is the key identifier used to perform the operation.
        public let keyIdentifier: String
        /// The plaintext to be encrypted.  For encryption using asymmetric keys, plaintext data length is constrained by encryption key strength that you define in KeyAlgorithm and padding type that you define in AsymmetricEncryptionAttributes. For more information, see Encrypt data in the Amazon Web Services Payment Cryptography User Guide.
        public let plainText: String
        /// The WrappedKeyBlock containing the encryption key for plaintext encryption.
        public let wrappedKey: WrappedKey?

        @inlinable
        public init(encryptionAttributes: EncryptionDecryptionAttributes, keyIdentifier: String, plainText: String, wrappedKey: WrappedKey? = nil) {
            self.encryptionAttributes = encryptionAttributes
            self.keyIdentifier = keyIdentifier
            self.plainText = plainText
            self.wrappedKey = wrappedKey
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.encryptionAttributes, forKey: .encryptionAttributes)
            request.encodePath(self.keyIdentifier, key: "KeyIdentifier")
            try container.encode(self.plainText, forKey: .plainText)
            try container.encodeIfPresent(self.wrappedKey, forKey: .wrappedKey)
        }

        public func validate(name: String) throws {
            try self.encryptionAttributes.validate(name: "\(name).encryptionAttributes")
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.plainText, name: "plainText", parent: name, max: 4096)
            try self.validate(self.plainText, name: "plainText", parent: name, min: 2)
            try self.validate(self.plainText, name: "plainText", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.wrappedKey?.validate(name: "\(name).wrappedKey")
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionAttributes = "EncryptionAttributes"
            case plainText = "PlainText"
            case wrappedKey = "WrappedKey"
        }
    }

    public struct EncryptDataOutput: AWSDecodableShape {
        /// The encrypted ciphertext.
        public let cipherText: String
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses for plaintext encryption.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String?

        @inlinable
        public init(cipherText: String, keyArn: String, keyCheckValue: String? = nil) {
            self.cipherText = cipherText
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case cipherText = "CipherText"
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
        }
    }

    public struct GenerateCardValidationDataInput: AWSEncodableShape {
        /// The algorithm for generating CVV or CSC values for the card within Amazon Web Services Payment Cryptography.
        public let generationAttributes: CardGenerationAttributes
        /// The keyARN of the CVK encryption key that Amazon Web Services Payment Cryptography uses to generate card data.
        public let keyIdentifier: String
        /// The Primary Account Number (PAN), a unique identifier for a payment credit or debit card that associates the card with a specific account holder.
        public let primaryAccountNumber: String
        /// The length of the CVV or CSC to be generated. The default value is 3.
        public let validationDataLength: Int?

        @inlinable
        public init(generationAttributes: CardGenerationAttributes, keyIdentifier: String, primaryAccountNumber: String, validationDataLength: Int? = nil) {
            self.generationAttributes = generationAttributes
            self.keyIdentifier = keyIdentifier
            self.primaryAccountNumber = primaryAccountNumber
            self.validationDataLength = validationDataLength
        }

        public func validate(name: String) throws {
            try self.generationAttributes.validate(name: "\(name).generationAttributes")
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.validationDataLength, name: "validationDataLength", parent: name, max: 5)
            try self.validate(self.validationDataLength, name: "validationDataLength", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case generationAttributes = "GenerationAttributes"
            case keyIdentifier = "KeyIdentifier"
            case primaryAccountNumber = "PrimaryAccountNumber"
            case validationDataLength = "ValidationDataLength"
        }
    }

    public struct GenerateCardValidationDataOutput: AWSDecodableShape {
        /// The keyARN of the CVK encryption key that Amazon Web Services Payment Cryptography uses to generate CVV or CSC.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String
        /// The CVV or CSC value that Amazon Web Services Payment Cryptography generates for the card.
        public let validationData: String

        @inlinable
        public init(keyArn: String, keyCheckValue: String, validationData: String) {
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
            self.validationData = validationData
        }

        private enum CodingKeys: String, CodingKey {
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
            case validationData = "ValidationData"
        }
    }

    public struct GenerateMacEmvPinChangeInput: AWSEncodableShape {
        /// The attributes and data values to derive payment card specific confidentiality and integrity keys.
        public let derivationMethodAttributes: DerivationMethodAttributes
        /// The message data is the APDU command from the card reader or terminal. The target encrypted PIN block, after translation to ISO2 format, is appended to this message data to generate an issuer script response.
        public let messageData: String
        /// The incoming new encrypted PIN block data for offline pin change on an EMV card.
        public let newEncryptedPinBlock: String
        /// The keyARN of the PEK protecting the incoming new encrypted PIN block.
        public let newPinPekIdentifier: String
        /// The PIN encoding format of the incoming new encrypted PIN block as specified in ISO 9564.
        public let pinBlockFormat: PinBlockFormatForEmvPinChange
        /// The keyARN of the issuer master key (IMK-SMC) used to protect the PIN block data in the issuer script response.
        public let secureMessagingConfidentialityKeyIdentifier: String
        /// The keyARN of the issuer master key (IMK-SMI) used to authenticate the issuer script response.
        public let secureMessagingIntegrityKeyIdentifier: String

        @inlinable
        public init(derivationMethodAttributes: DerivationMethodAttributes, messageData: String, newEncryptedPinBlock: String, newPinPekIdentifier: String, pinBlockFormat: PinBlockFormatForEmvPinChange, secureMessagingConfidentialityKeyIdentifier: String, secureMessagingIntegrityKeyIdentifier: String) {
            self.derivationMethodAttributes = derivationMethodAttributes
            self.messageData = messageData
            self.newEncryptedPinBlock = newEncryptedPinBlock
            self.newPinPekIdentifier = newPinPekIdentifier
            self.pinBlockFormat = pinBlockFormat
            self.secureMessagingConfidentialityKeyIdentifier = secureMessagingConfidentialityKeyIdentifier
            self.secureMessagingIntegrityKeyIdentifier = secureMessagingIntegrityKeyIdentifier
        }

        public func validate(name: String) throws {
            try self.derivationMethodAttributes.validate(name: "\(name).derivationMethodAttributes")
            try self.validate(self.messageData, name: "messageData", parent: name, max: 1024)
            try self.validate(self.messageData, name: "messageData", parent: name, min: 16)
            try self.validate(self.messageData, name: "messageData", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.validate(self.newEncryptedPinBlock, name: "newEncryptedPinBlock", parent: name, max: 16)
            try self.validate(self.newEncryptedPinBlock, name: "newEncryptedPinBlock", parent: name, min: 16)
            try self.validate(self.newEncryptedPinBlock, name: "newEncryptedPinBlock", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.newPinPekIdentifier, name: "newPinPekIdentifier", parent: name, max: 322)
            try self.validate(self.newPinPekIdentifier, name: "newPinPekIdentifier", parent: name, min: 7)
            try self.validate(self.newPinPekIdentifier, name: "newPinPekIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.secureMessagingConfidentialityKeyIdentifier, name: "secureMessagingConfidentialityKeyIdentifier", parent: name, max: 322)
            try self.validate(self.secureMessagingConfidentialityKeyIdentifier, name: "secureMessagingConfidentialityKeyIdentifier", parent: name, min: 7)
            try self.validate(self.secureMessagingConfidentialityKeyIdentifier, name: "secureMessagingConfidentialityKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.secureMessagingIntegrityKeyIdentifier, name: "secureMessagingIntegrityKeyIdentifier", parent: name, max: 322)
            try self.validate(self.secureMessagingIntegrityKeyIdentifier, name: "secureMessagingIntegrityKeyIdentifier", parent: name, min: 7)
            try self.validate(self.secureMessagingIntegrityKeyIdentifier, name: "secureMessagingIntegrityKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case derivationMethodAttributes = "DerivationMethodAttributes"
            case messageData = "MessageData"
            case newEncryptedPinBlock = "NewEncryptedPinBlock"
            case newPinPekIdentifier = "NewPinPekIdentifier"
            case pinBlockFormat = "PinBlockFormat"
            case secureMessagingConfidentialityKeyIdentifier = "SecureMessagingConfidentialityKeyIdentifier"
            case secureMessagingIntegrityKeyIdentifier = "SecureMessagingIntegrityKeyIdentifier"
        }
    }

    public struct GenerateMacEmvPinChangeOutput: AWSDecodableShape {
        /// Returns the incoming new encrpted PIN block.
        public let encryptedPinBlock: String
        /// Returns the mac of the issuer script containing message data and appended target encrypted pin block in ISO2 format.
        public let mac: String
        /// Returns the keyArn of the PEK protecting the incoming new encrypted PIN block.
        public let newPinPekArn: String
        /// The key check value (KCV) of the PEK uprotecting the incoming new encrypted PIN block.
        public let newPinPekKeyCheckValue: String
        /// Returns the keyArn of the IMK-SMC used by the operation.
        public let secureMessagingConfidentialityKeyArn: String
        /// The key check value (KCV) of the SMC issuer master key used by the operation.
        public let secureMessagingConfidentialityKeyCheckValue: String
        /// Returns the keyArn of the IMK-SMI used by the operation.
        public let secureMessagingIntegrityKeyArn: String
        /// The key check value (KCV) of the SMI issuer master key used by the operation.
        public let secureMessagingIntegrityKeyCheckValue: String
        /// The attribute values used for Amex and Visa derivation methods.
        public let visaAmexDerivationOutputs: VisaAmexDerivationOutputs?

        @inlinable
        public init(encryptedPinBlock: String, mac: String, newPinPekArn: String, newPinPekKeyCheckValue: String, secureMessagingConfidentialityKeyArn: String, secureMessagingConfidentialityKeyCheckValue: String, secureMessagingIntegrityKeyArn: String, secureMessagingIntegrityKeyCheckValue: String, visaAmexDerivationOutputs: VisaAmexDerivationOutputs? = nil) {
            self.encryptedPinBlock = encryptedPinBlock
            self.mac = mac
            self.newPinPekArn = newPinPekArn
            self.newPinPekKeyCheckValue = newPinPekKeyCheckValue
            self.secureMessagingConfidentialityKeyArn = secureMessagingConfidentialityKeyArn
            self.secureMessagingConfidentialityKeyCheckValue = secureMessagingConfidentialityKeyCheckValue
            self.secureMessagingIntegrityKeyArn = secureMessagingIntegrityKeyArn
            self.secureMessagingIntegrityKeyCheckValue = secureMessagingIntegrityKeyCheckValue
            self.visaAmexDerivationOutputs = visaAmexDerivationOutputs
        }

        private enum CodingKeys: String, CodingKey {
            case encryptedPinBlock = "EncryptedPinBlock"
            case mac = "Mac"
            case newPinPekArn = "NewPinPekArn"
            case newPinPekKeyCheckValue = "NewPinPekKeyCheckValue"
            case secureMessagingConfidentialityKeyArn = "SecureMessagingConfidentialityKeyArn"
            case secureMessagingConfidentialityKeyCheckValue = "SecureMessagingConfidentialityKeyCheckValue"
            case secureMessagingIntegrityKeyArn = "SecureMessagingIntegrityKeyArn"
            case secureMessagingIntegrityKeyCheckValue = "SecureMessagingIntegrityKeyCheckValue"
            case visaAmexDerivationOutputs = "VisaAmexDerivationOutputs"
        }
    }

    public struct GenerateMacInput: AWSEncodableShape {
        /// The attributes and data values to use for MAC generation within Amazon Web Services Payment Cryptography.
        public let generationAttributes: MacAttributes
        /// The keyARN of the MAC generation encryption key.
        public let keyIdentifier: String
        /// The length of a MAC under generation.
        public let macLength: Int?
        /// The data for which a MAC is under generation. This value must be hexBinary.
        public let messageData: String

        @inlinable
        public init(generationAttributes: MacAttributes, keyIdentifier: String, macLength: Int? = nil, messageData: String) {
            self.generationAttributes = generationAttributes
            self.keyIdentifier = keyIdentifier
            self.macLength = macLength
            self.messageData = messageData
        }

        public func validate(name: String) throws {
            try self.generationAttributes.validate(name: "\(name).generationAttributes")
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.macLength, name: "macLength", parent: name, max: 16)
            try self.validate(self.macLength, name: "macLength", parent: name, min: 4)
            try self.validate(self.messageData, name: "messageData", parent: name, max: 8192)
            try self.validate(self.messageData, name: "messageData", parent: name, min: 2)
            try self.validate(self.messageData, name: "messageData", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
        }

        private enum CodingKeys: String, CodingKey {
            case generationAttributes = "GenerationAttributes"
            case keyIdentifier = "KeyIdentifier"
            case macLength = "MacLength"
            case messageData = "MessageData"
        }
    }

    public struct GenerateMacOutput: AWSDecodableShape {
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses for MAC generation.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String
        /// The MAC cryptogram generated within Amazon Web Services Payment Cryptography.
        public let mac: String

        @inlinable
        public init(keyArn: String, keyCheckValue: String, mac: String) {
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
            self.mac = mac
        }

        private enum CodingKeys: String, CodingKey {
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
            case mac = "Mac"
        }
    }

    public struct GeneratePinDataInput: AWSEncodableShape {
        /// The keyARN of the PEK that Amazon Web Services Payment Cryptography uses to encrypt the PIN Block. For ECDH, it is the keyARN of the asymmetric ECC key.
        public let encryptionKeyIdentifier: String
        public let encryptionWrappedKey: WrappedKey?
        /// The attributes and values to use for PIN, PVV, or PIN Offset generation.
        public let generationAttributes: PinGenerationAttributes
        /// The keyARN of the PEK that Amazon Web Services Payment Cryptography uses for pin data generation.
        public let generationKeyIdentifier: String
        /// The PIN encoding format for pin data generation as specified in ISO 9564. Amazon Web Services Payment Cryptography supports ISO_Format_0 and ISO_Format_3. The ISO_Format_0 PIN block format is equivalent to the ANSI X9.8, VISA-1, and ECI-1 PIN block formats. It is similar to a VISA-4 PIN block format. It supports a PIN from 4 to 12 digits in length. The ISO_Format_3 PIN block format is the same as ISO_Format_0 except that the fill digits are random values from 10 to 15.
        public let pinBlockFormat: PinBlockFormatForPinData
        /// The length of PIN under generation.
        public let pinDataLength: Int?
        /// The Primary Account Number (PAN), a unique identifier for a payment credit or debit card that associates the card with a specific account holder.
        public let primaryAccountNumber: String

        @inlinable
        public init(encryptionKeyIdentifier: String, encryptionWrappedKey: WrappedKey? = nil, generationAttributes: PinGenerationAttributes, generationKeyIdentifier: String, pinBlockFormat: PinBlockFormatForPinData, pinDataLength: Int? = nil, primaryAccountNumber: String) {
            self.encryptionKeyIdentifier = encryptionKeyIdentifier
            self.encryptionWrappedKey = encryptionWrappedKey
            self.generationAttributes = generationAttributes
            self.generationKeyIdentifier = generationKeyIdentifier
            self.pinBlockFormat = pinBlockFormat
            self.pinDataLength = pinDataLength
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.encryptionKeyIdentifier, name: "encryptionKeyIdentifier", parent: name, max: 322)
            try self.validate(self.encryptionKeyIdentifier, name: "encryptionKeyIdentifier", parent: name, min: 7)
            try self.validate(self.encryptionKeyIdentifier, name: "encryptionKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.encryptionWrappedKey?.validate(name: "\(name).encryptionWrappedKey")
            try self.generationAttributes.validate(name: "\(name).generationAttributes")
            try self.validate(self.generationKeyIdentifier, name: "generationKeyIdentifier", parent: name, max: 322)
            try self.validate(self.generationKeyIdentifier, name: "generationKeyIdentifier", parent: name, min: 7)
            try self.validate(self.generationKeyIdentifier, name: "generationKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.pinDataLength, name: "pinDataLength", parent: name, max: 12)
            try self.validate(self.pinDataLength, name: "pinDataLength", parent: name, min: 4)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionKeyIdentifier = "EncryptionKeyIdentifier"
            case encryptionWrappedKey = "EncryptionWrappedKey"
            case generationAttributes = "GenerationAttributes"
            case generationKeyIdentifier = "GenerationKeyIdentifier"
            case pinBlockFormat = "PinBlockFormat"
            case pinDataLength = "PinDataLength"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct GeneratePinDataOutput: AWSDecodableShape {
        /// The PIN block encrypted under PEK from Amazon Web Services Payment Cryptography. The encrypted PIN block is a composite of PAN (Primary Account Number) and PIN (Personal Identification Number), generated in accordance with ISO 9564 standard.
        public let encryptedPinBlock: String
        /// The keyARN of the PEK that Amazon Web Services Payment Cryptography uses for encrypted pin block generation. For ECDH, it is the keyARN of the asymmetric ECC key.
        public let encryptionKeyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let encryptionKeyCheckValue: String
        /// The keyARN of the pin data generation key that Amazon Web Services Payment Cryptography uses for PIN, PVV or PIN Offset generation.
        public let generationKeyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let generationKeyCheckValue: String
        /// The attributes and values Amazon Web Services Payment Cryptography uses for pin data generation.
        public let pinData: PinData

        @inlinable
        public init(encryptedPinBlock: String, encryptionKeyArn: String, encryptionKeyCheckValue: String, generationKeyArn: String, generationKeyCheckValue: String, pinData: PinData) {
            self.encryptedPinBlock = encryptedPinBlock
            self.encryptionKeyArn = encryptionKeyArn
            self.encryptionKeyCheckValue = encryptionKeyCheckValue
            self.generationKeyArn = generationKeyArn
            self.generationKeyCheckValue = generationKeyCheckValue
            self.pinData = pinData
        }

        private enum CodingKeys: String, CodingKey {
            case encryptedPinBlock = "EncryptedPinBlock"
            case encryptionKeyArn = "EncryptionKeyArn"
            case encryptionKeyCheckValue = "EncryptionKeyCheckValue"
            case generationKeyArn = "GenerationKeyArn"
            case generationKeyCheckValue = "GenerationKeyCheckValue"
            case pinData = "PinData"
        }
    }

    public struct Ibm3624NaturalPin: AWSEncodableShape {
        /// The decimalization table to use for IBM 3624 PIN algorithm. The table is used to convert the algorithm intermediate result from hexadecimal characters to decimal.
        public let decimalizationTable: String
        /// The unique data for cardholder identification.
        public let pinValidationData: String
        /// The padding character for validation data.
        public let pinValidationDataPadCharacter: String

        @inlinable
        public init(decimalizationTable: String, pinValidationData: String, pinValidationDataPadCharacter: String) {
            self.decimalizationTable = decimalizationTable
            self.pinValidationData = pinValidationData
            self.pinValidationDataPadCharacter = pinValidationDataPadCharacter
        }

        public func validate(name: String) throws {
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, max: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, min: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, max: 16)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, min: 4)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, max: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, min: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, pattern: "^[0-9A-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case decimalizationTable = "DecimalizationTable"
            case pinValidationData = "PinValidationData"
            case pinValidationDataPadCharacter = "PinValidationDataPadCharacter"
        }
    }

    public struct Ibm3624PinFromOffset: AWSEncodableShape {
        /// The decimalization table to use for IBM 3624 PIN algorithm. The table is used to convert the algorithm intermediate result from hexadecimal characters to decimal.
        public let decimalizationTable: String
        /// The PIN offset value.
        public let pinOffset: String
        /// The unique data for cardholder identification.
        public let pinValidationData: String
        /// The padding character for validation data.
        public let pinValidationDataPadCharacter: String

        @inlinable
        public init(decimalizationTable: String, pinOffset: String, pinValidationData: String, pinValidationDataPadCharacter: String) {
            self.decimalizationTable = decimalizationTable
            self.pinOffset = pinOffset
            self.pinValidationData = pinValidationData
            self.pinValidationDataPadCharacter = pinValidationDataPadCharacter
        }

        public func validate(name: String) throws {
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, max: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, min: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinOffset, name: "pinOffset", parent: name, max: 12)
            try self.validate(self.pinOffset, name: "pinOffset", parent: name, min: 4)
            try self.validate(self.pinOffset, name: "pinOffset", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, max: 16)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, min: 4)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, max: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, min: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, pattern: "^[0-9A-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case decimalizationTable = "DecimalizationTable"
            case pinOffset = "PinOffset"
            case pinValidationData = "PinValidationData"
            case pinValidationDataPadCharacter = "PinValidationDataPadCharacter"
        }
    }

    public struct Ibm3624PinOffset: AWSEncodableShape {
        /// The decimalization table to use for IBM 3624 PIN algorithm. The table is used to convert the algorithm intermediate result from hexadecimal characters to decimal.
        public let decimalizationTable: String
        /// The encrypted PIN block data. According to ISO 9564 standard, a PIN Block is an encoded representation of a payment card Personal Account Number (PAN) and the cardholder Personal Identification Number (PIN).
        public let encryptedPinBlock: String
        /// The unique data for cardholder identification.
        public let pinValidationData: String
        /// The padding character for validation data.
        public let pinValidationDataPadCharacter: String

        @inlinable
        public init(decimalizationTable: String, encryptedPinBlock: String, pinValidationData: String, pinValidationDataPadCharacter: String) {
            self.decimalizationTable = decimalizationTable
            self.encryptedPinBlock = encryptedPinBlock
            self.pinValidationData = pinValidationData
            self.pinValidationDataPadCharacter = pinValidationDataPadCharacter
        }

        public func validate(name: String) throws {
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, max: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, min: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, max: 32)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, min: 16)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, max: 16)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, min: 4)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, max: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, min: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, pattern: "^[0-9A-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case decimalizationTable = "DecimalizationTable"
            case encryptedPinBlock = "EncryptedPinBlock"
            case pinValidationData = "PinValidationData"
            case pinValidationDataPadCharacter = "PinValidationDataPadCharacter"
        }
    }

    public struct Ibm3624PinVerification: AWSEncodableShape {
        /// The decimalization table to use for IBM 3624 PIN algorithm. The table is used to convert the algorithm intermediate result from hexadecimal characters to decimal.
        public let decimalizationTable: String
        /// The PIN offset value.
        public let pinOffset: String
        /// The unique data for cardholder identification.
        public let pinValidationData: String
        /// The padding character for validation data.
        public let pinValidationDataPadCharacter: String

        @inlinable
        public init(decimalizationTable: String, pinOffset: String, pinValidationData: String, pinValidationDataPadCharacter: String) {
            self.decimalizationTable = decimalizationTable
            self.pinOffset = pinOffset
            self.pinValidationData = pinValidationData
            self.pinValidationDataPadCharacter = pinValidationDataPadCharacter
        }

        public func validate(name: String) throws {
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, max: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, min: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinOffset, name: "pinOffset", parent: name, max: 12)
            try self.validate(self.pinOffset, name: "pinOffset", parent: name, min: 4)
            try self.validate(self.pinOffset, name: "pinOffset", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, max: 16)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, min: 4)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, max: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, min: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, pattern: "^[0-9A-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case decimalizationTable = "DecimalizationTable"
            case pinOffset = "PinOffset"
            case pinValidationData = "PinValidationData"
            case pinValidationDataPadCharacter = "PinValidationDataPadCharacter"
        }
    }

    public struct Ibm3624RandomPin: AWSEncodableShape {
        /// The decimalization table to use for IBM 3624 PIN algorithm. The table is used to convert the algorithm intermediate result from hexadecimal characters to decimal.
        public let decimalizationTable: String
        /// The unique data for cardholder identification.
        public let pinValidationData: String
        /// The padding character for validation data.
        public let pinValidationDataPadCharacter: String

        @inlinable
        public init(decimalizationTable: String, pinValidationData: String, pinValidationDataPadCharacter: String) {
            self.decimalizationTable = decimalizationTable
            self.pinValidationData = pinValidationData
            self.pinValidationDataPadCharacter = pinValidationDataPadCharacter
        }

        public func validate(name: String) throws {
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, max: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, min: 16)
            try self.validate(self.decimalizationTable, name: "decimalizationTable", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, max: 16)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, min: 4)
            try self.validate(self.pinValidationData, name: "pinValidationData", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, max: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, min: 1)
            try self.validate(self.pinValidationDataPadCharacter, name: "pinValidationDataPadCharacter", parent: name, pattern: "^[0-9A-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case decimalizationTable = "DecimalizationTable"
            case pinValidationData = "PinValidationData"
            case pinValidationDataPadCharacter = "PinValidationDataPadCharacter"
        }
    }

    public struct MacAlgorithmDukpt: AWSEncodableShape {
        /// The key type derived using DUKPT from a Base Derivation Key (BDK) and Key Serial Number (KSN). This must be less than or equal to the strength of the BDK. For example, you can't use AES_128 as a derivation type for a BDK of AES_128 or TDES_2KEY.
        public let dukptDerivationType: DukptDerivationType?
        /// The type of use of DUKPT, which can be MAC generation, MAC verification, or both.
        public let dukptKeyVariant: DukptKeyVariant
        /// The unique identifier known as Key Serial Number (KSN) that comes from an encrypting device using DUKPT encryption method. The KSN is derived from the encrypting device unique identifier and an internal transaction counter.
        public let keySerialNumber: String

        @inlinable
        public init(dukptDerivationType: DukptDerivationType? = nil, dukptKeyVariant: DukptKeyVariant, keySerialNumber: String) {
            self.dukptDerivationType = dukptDerivationType
            self.dukptKeyVariant = dukptKeyVariant
            self.keySerialNumber = keySerialNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, max: 24)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, min: 16)
            try self.validate(self.keySerialNumber, name: "keySerialNumber", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{20}|[0-9a-fA-F]{24})$")
        }

        private enum CodingKeys: String, CodingKey {
            case dukptDerivationType = "DukptDerivationType"
            case dukptKeyVariant = "DukptKeyVariant"
            case keySerialNumber = "KeySerialNumber"
        }
    }

    public struct MacAlgorithmEmv: AWSEncodableShape {
        /// The method to use when deriving the master key for EMV MAC generation or verification.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN), a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String
        /// The method of deriving a session key for EMV MAC generation or verification.
        public let sessionKeyDerivationMode: SessionKeyDerivationMode
        /// Parameters that are required to generate session key for EMV generation and verification.
        public let sessionKeyDerivationValue: SessionKeyDerivationValue

        @inlinable
        public init(majorKeyDerivationMode: MajorKeyDerivationMode, panSequenceNumber: String, primaryAccountNumber: String, sessionKeyDerivationMode: SessionKeyDerivationMode, sessionKeyDerivationValue: SessionKeyDerivationValue) {
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
            self.sessionKeyDerivationMode = sessionKeyDerivationMode
            self.sessionKeyDerivationValue = sessionKeyDerivationValue
        }

        public func validate(name: String) throws {
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
            try self.sessionKeyDerivationValue.validate(name: "\(name).sessionKeyDerivationValue")
        }

        private enum CodingKeys: String, CodingKey {
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
            case sessionKeyDerivationMode = "SessionKeyDerivationMode"
            case sessionKeyDerivationValue = "SessionKeyDerivationValue"
        }
    }

    public struct MasterCardAttributes: AWSEncodableShape {
        /// The application cryptogram for the current transaction that is provided by the terminal during transaction processing.
        public let applicationCryptogram: String
        /// The method to use when deriving the master key for the payment card.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN). Typically 00 is used, if no value is provided by the terminal.
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationCryptogram: String, majorKeyDerivationMode: MajorKeyDerivationMode, panSequenceNumber: String, primaryAccountNumber: String) {
            self.applicationCryptogram = applicationCryptogram
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationCryptogram, name: "applicationCryptogram", parent: name, max: 16)
            try self.validate(self.applicationCryptogram, name: "applicationCryptogram", parent: name, min: 16)
            try self.validate(self.applicationCryptogram, name: "applicationCryptogram", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationCryptogram = "ApplicationCryptogram"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct ReEncryptDataInput: AWSEncodableShape {
        /// Ciphertext to be encrypted. The minimum allowed length is 16 bytes and maximum allowed length is 4096 bytes.
        public let cipherText: String
        /// The attributes and values for incoming ciphertext.
        public let incomingEncryptionAttributes: ReEncryptionAttributes
        /// The keyARN of the encryption key of incoming ciphertext data. When a WrappedKeyBlock is provided, this value will be the identifier to the key wrapping key. Otherwise, it is the key identifier used to perform the operation.
        public let incomingKeyIdentifier: String
        /// The WrappedKeyBlock containing the encryption key of incoming ciphertext data.
        public let incomingWrappedKey: WrappedKey?
        /// The attributes and values for outgoing ciphertext data after encryption by Amazon Web Services Payment Cryptography.
        public let outgoingEncryptionAttributes: ReEncryptionAttributes
        /// The keyARN of the encryption key of outgoing ciphertext data after encryption by Amazon Web Services Payment Cryptography.
        public let outgoingKeyIdentifier: String
        /// The WrappedKeyBlock containing the encryption key of outgoing ciphertext data after encryption by Amazon Web Services Payment Cryptography.
        public let outgoingWrappedKey: WrappedKey?

        @inlinable
        public init(cipherText: String, incomingEncryptionAttributes: ReEncryptionAttributes, incomingKeyIdentifier: String, incomingWrappedKey: WrappedKey? = nil, outgoingEncryptionAttributes: ReEncryptionAttributes, outgoingKeyIdentifier: String, outgoingWrappedKey: WrappedKey? = nil) {
            self.cipherText = cipherText
            self.incomingEncryptionAttributes = incomingEncryptionAttributes
            self.incomingKeyIdentifier = incomingKeyIdentifier
            self.incomingWrappedKey = incomingWrappedKey
            self.outgoingEncryptionAttributes = outgoingEncryptionAttributes
            self.outgoingKeyIdentifier = outgoingKeyIdentifier
            self.outgoingWrappedKey = outgoingWrappedKey
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.cipherText, forKey: .cipherText)
            try container.encode(self.incomingEncryptionAttributes, forKey: .incomingEncryptionAttributes)
            request.encodePath(self.incomingKeyIdentifier, key: "IncomingKeyIdentifier")
            try container.encodeIfPresent(self.incomingWrappedKey, forKey: .incomingWrappedKey)
            try container.encode(self.outgoingEncryptionAttributes, forKey: .outgoingEncryptionAttributes)
            try container.encode(self.outgoingKeyIdentifier, forKey: .outgoingKeyIdentifier)
            try container.encodeIfPresent(self.outgoingWrappedKey, forKey: .outgoingWrappedKey)
        }

        public func validate(name: String) throws {
            try self.validate(self.cipherText, name: "cipherText", parent: name, max: 4224)
            try self.validate(self.cipherText, name: "cipherText", parent: name, min: 2)
            try self.validate(self.cipherText, name: "cipherText", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.incomingEncryptionAttributes.validate(name: "\(name).incomingEncryptionAttributes")
            try self.validate(self.incomingKeyIdentifier, name: "incomingKeyIdentifier", parent: name, max: 322)
            try self.validate(self.incomingKeyIdentifier, name: "incomingKeyIdentifier", parent: name, min: 7)
            try self.validate(self.incomingKeyIdentifier, name: "incomingKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.incomingWrappedKey?.validate(name: "\(name).incomingWrappedKey")
            try self.outgoingEncryptionAttributes.validate(name: "\(name).outgoingEncryptionAttributes")
            try self.validate(self.outgoingKeyIdentifier, name: "outgoingKeyIdentifier", parent: name, max: 322)
            try self.validate(self.outgoingKeyIdentifier, name: "outgoingKeyIdentifier", parent: name, min: 7)
            try self.validate(self.outgoingKeyIdentifier, name: "outgoingKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.outgoingWrappedKey?.validate(name: "\(name).outgoingWrappedKey")
        }

        private enum CodingKeys: String, CodingKey {
            case cipherText = "CipherText"
            case incomingEncryptionAttributes = "IncomingEncryptionAttributes"
            case incomingWrappedKey = "IncomingWrappedKey"
            case outgoingEncryptionAttributes = "OutgoingEncryptionAttributes"
            case outgoingKeyIdentifier = "OutgoingKeyIdentifier"
            case outgoingWrappedKey = "OutgoingWrappedKey"
        }
    }

    public struct ReEncryptDataOutput: AWSDecodableShape {
        /// The encrypted ciphertext.
        public let cipherText: String
        /// The keyARN (Amazon Resource Name) of the encryption key that Amazon Web Services Payment Cryptography uses for plaintext encryption.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String

        @inlinable
        public init(cipherText: String, keyArn: String, keyCheckValue: String) {
            self.cipherText = cipherText
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case cipherText = "CipherText"
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        /// The resource that is missing.
        public let resourceId: String?

        @inlinable
        public init(resourceId: String? = nil) {
            self.resourceId = resourceId
        }

        private enum CodingKeys: String, CodingKey {
            case resourceId = "ResourceId"
        }
    }

    public struct SessionKeyAmex: AWSEncodableShape {
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder. A PAN is a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String

        @inlinable
        public init(panSequenceNumber: String, primaryAccountNumber: String) {
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct SessionKeyEmv2000: AWSEncodableShape {
        /// The transaction counter that is provided by the terminal during transaction processing.
        public let applicationTransactionCounter: String
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder. A PAN is a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, panSequenceNumber: String, primaryAccountNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct SessionKeyEmvCommon: AWSEncodableShape {
        /// The transaction counter that is provided by the terminal during transaction processing.
        public let applicationTransactionCounter: String
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder. A PAN is a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, panSequenceNumber: String, primaryAccountNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct SessionKeyMastercard: AWSEncodableShape {
        /// The transaction counter that is provided by the terminal during transaction processing.
        public let applicationTransactionCounter: String
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder. A PAN is a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String
        /// A random number generated by the issuer.
        public let unpredictableNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, panSequenceNumber: String, primaryAccountNumber: String, unpredictableNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
            self.unpredictableNumber = unpredictableNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, max: 8)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, min: 2)
            try self.validate(self.unpredictableNumber, name: "unpredictableNumber", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
            case unpredictableNumber = "UnpredictableNumber"
        }
    }

    public struct SessionKeyVisa: AWSEncodableShape {
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN).
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder. A PAN is a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String

        @inlinable
        public init(panSequenceNumber: String, primaryAccountNumber: String) {
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct SymmetricEncryptionAttributes: AWSEncodableShape {
        /// An input used to provide the intial state. If no value is provided, Amazon Web Services Payment Cryptography defaults it to zero.
        public let initializationVector: String?
        /// The block cipher method to use for encryption.
        public let mode: EncryptionMode
        /// The padding to be included with the data.
        public let paddingType: PaddingType?

        @inlinable
        public init(initializationVector: String? = nil, mode: EncryptionMode, paddingType: PaddingType? = nil) {
            self.initializationVector = initializationVector
            self.mode = mode
            self.paddingType = paddingType
        }

        public func validate(name: String) throws {
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, max: 32)
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, min: 16)
            try self.validate(self.initializationVector, name: "initializationVector", parent: name, pattern: "^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{32})$")
        }

        private enum CodingKeys: String, CodingKey {
            case initializationVector = "InitializationVector"
            case mode = "Mode"
            case paddingType = "PaddingType"
        }
    }

    public struct TranslatePinDataInput: AWSEncodableShape {
        /// The encrypted PIN block data that Amazon Web Services Payment Cryptography translates.
        public let encryptedPinBlock: String
        /// The attributes and values to use for incoming DUKPT encryption key for PIN block translation.
        public let incomingDukptAttributes: DukptDerivationAttributes?
        /// The keyARN of the encryption key under which incoming PIN block data is encrypted. This key type can be PEK or BDK. For dynamic keys, it is the keyARN of KEK of the TR-31 wrapped PEK. For ECDH, it is the keyARN of the asymmetric ECC key.
        public let incomingKeyIdentifier: String
        /// The format of the incoming PIN block data for translation within Amazon Web Services Payment Cryptography.
        public let incomingTranslationAttributes: TranslationIsoFormats
        /// The WrappedKeyBlock containing the encryption key under which incoming PIN block data is encrypted.
        public let incomingWrappedKey: WrappedKey?
        /// The attributes and values to use for outgoing DUKPT encryption key after PIN block translation.
        public let outgoingDukptAttributes: DukptDerivationAttributes?
        /// The keyARN of the encryption key for encrypting outgoing PIN block data. This key type can be PEK or BDK. For ECDH, it is the keyARN of the asymmetric ECC key.
        public let outgoingKeyIdentifier: String
        /// The format of the outgoing PIN block data after translation by Amazon Web Services Payment Cryptography.
        public let outgoingTranslationAttributes: TranslationIsoFormats
        /// The WrappedKeyBlock containing the encryption key for encrypting outgoing PIN block data.
        public let outgoingWrappedKey: WrappedKey?

        @inlinable
        public init(encryptedPinBlock: String, incomingDukptAttributes: DukptDerivationAttributes? = nil, incomingKeyIdentifier: String, incomingTranslationAttributes: TranslationIsoFormats, incomingWrappedKey: WrappedKey? = nil, outgoingDukptAttributes: DukptDerivationAttributes? = nil, outgoingKeyIdentifier: String, outgoingTranslationAttributes: TranslationIsoFormats, outgoingWrappedKey: WrappedKey? = nil) {
            self.encryptedPinBlock = encryptedPinBlock
            self.incomingDukptAttributes = incomingDukptAttributes
            self.incomingKeyIdentifier = incomingKeyIdentifier
            self.incomingTranslationAttributes = incomingTranslationAttributes
            self.incomingWrappedKey = incomingWrappedKey
            self.outgoingDukptAttributes = outgoingDukptAttributes
            self.outgoingKeyIdentifier = outgoingKeyIdentifier
            self.outgoingTranslationAttributes = outgoingTranslationAttributes
            self.outgoingWrappedKey = outgoingWrappedKey
        }

        public func validate(name: String) throws {
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, max: 32)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, min: 16)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.incomingDukptAttributes?.validate(name: "\(name).incomingDukptAttributes")
            try self.validate(self.incomingKeyIdentifier, name: "incomingKeyIdentifier", parent: name, max: 322)
            try self.validate(self.incomingKeyIdentifier, name: "incomingKeyIdentifier", parent: name, min: 7)
            try self.validate(self.incomingKeyIdentifier, name: "incomingKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.incomingTranslationAttributes.validate(name: "\(name).incomingTranslationAttributes")
            try self.incomingWrappedKey?.validate(name: "\(name).incomingWrappedKey")
            try self.outgoingDukptAttributes?.validate(name: "\(name).outgoingDukptAttributes")
            try self.validate(self.outgoingKeyIdentifier, name: "outgoingKeyIdentifier", parent: name, max: 322)
            try self.validate(self.outgoingKeyIdentifier, name: "outgoingKeyIdentifier", parent: name, min: 7)
            try self.validate(self.outgoingKeyIdentifier, name: "outgoingKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.outgoingTranslationAttributes.validate(name: "\(name).outgoingTranslationAttributes")
            try self.outgoingWrappedKey?.validate(name: "\(name).outgoingWrappedKey")
        }

        private enum CodingKeys: String, CodingKey {
            case encryptedPinBlock = "EncryptedPinBlock"
            case incomingDukptAttributes = "IncomingDukptAttributes"
            case incomingKeyIdentifier = "IncomingKeyIdentifier"
            case incomingTranslationAttributes = "IncomingTranslationAttributes"
            case incomingWrappedKey = "IncomingWrappedKey"
            case outgoingDukptAttributes = "OutgoingDukptAttributes"
            case outgoingKeyIdentifier = "OutgoingKeyIdentifier"
            case outgoingTranslationAttributes = "OutgoingTranslationAttributes"
            case outgoingWrappedKey = "OutgoingWrappedKey"
        }
    }

    public struct TranslatePinDataOutput: AWSDecodableShape {
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses to encrypt outgoing PIN block data after translation.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String
        /// The outgoing encrypted PIN block data after translation.
        public let pinBlock: String

        @inlinable
        public init(keyArn: String, keyCheckValue: String, pinBlock: String) {
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
            self.pinBlock = pinBlock
        }

        private enum CodingKeys: String, CodingKey {
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
            case pinBlock = "PinBlock"
        }
    }

    public struct TranslationPinDataIsoFormat034: AWSEncodableShape {
        /// The Primary Account Number (PAN) of the cardholder. A PAN is a unique identifier for a payment credit or debit card and associates the card to a specific account holder.
        public let primaryAccountNumber: String

        @inlinable
        public init(primaryAccountNumber: String) {
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct TranslationPinDataIsoFormat1: AWSEncodableShape {
        public init() {}
    }

    public struct ValidationException: AWSErrorShape {
        /// The request was denied due to an invalid request error.
        public let fieldList: [ValidationExceptionField]?
        public let message: String

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String) {
            self.fieldList = fieldList
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// The request was denied due to an invalid request error.
        public let message: String
        /// The request was denied due to an invalid request error.
        public let path: String

        @inlinable
        public init(message: String, path: String) {
            self.message = message
            self.path = path
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case path = "path"
        }
    }

    public struct VerificationFailedException: AWSErrorShape {
        public let message: String
        /// The reason for the exception.
        public let reason: VerificationFailedReason

        @inlinable
        public init(message: String, reason: VerificationFailedReason) {
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case reason = "Reason"
        }
    }

    public struct VerifyAuthRequestCryptogramInput: AWSEncodableShape {
        /// The auth request cryptogram imported into Amazon Web Services Payment Cryptography for ARQC verification using a major encryption key and transaction data.
        public let authRequestCryptogram: String
        /// The attributes and values for auth request cryptogram verification. These parameters are required in case using ARPC Method 1 or Method 2 for ARQC verification.
        public let authResponseAttributes: CryptogramAuthResponse?
        /// The keyARN of the major encryption key that Amazon Web Services Payment Cryptography uses for ARQC verification.
        public let keyIdentifier: String
        /// The method to use when deriving the major encryption key for ARQC verification within Amazon Web Services Payment Cryptography. The same key derivation mode was used for ARQC generation outside of Amazon Web Services Payment Cryptography.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// The attributes and values to use for deriving a session key for ARQC verification within Amazon Web Services Payment Cryptography. The same attributes were used for ARQC generation outside of Amazon Web Services Payment Cryptography.
        public let sessionKeyDerivationAttributes: SessionKeyDerivation
        /// The transaction data that Amazon Web Services Payment Cryptography uses for ARQC verification. The same transaction is used for ARQC generation outside of Amazon Web Services Payment Cryptography.
        public let transactionData: String

        @inlinable
        public init(authRequestCryptogram: String, authResponseAttributes: CryptogramAuthResponse? = nil, keyIdentifier: String, majorKeyDerivationMode: MajorKeyDerivationMode, sessionKeyDerivationAttributes: SessionKeyDerivation, transactionData: String) {
            self.authRequestCryptogram = authRequestCryptogram
            self.authResponseAttributes = authResponseAttributes
            self.keyIdentifier = keyIdentifier
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.sessionKeyDerivationAttributes = sessionKeyDerivationAttributes
            self.transactionData = transactionData
        }

        public func validate(name: String) throws {
            try self.validate(self.authRequestCryptogram, name: "authRequestCryptogram", parent: name, max: 16)
            try self.validate(self.authRequestCryptogram, name: "authRequestCryptogram", parent: name, min: 16)
            try self.validate(self.authRequestCryptogram, name: "authRequestCryptogram", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.authResponseAttributes?.validate(name: "\(name).authResponseAttributes")
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.sessionKeyDerivationAttributes.validate(name: "\(name).sessionKeyDerivationAttributes")
            try self.validate(self.transactionData, name: "transactionData", parent: name, max: 1024)
            try self.validate(self.transactionData, name: "transactionData", parent: name, min: 2)
            try self.validate(self.transactionData, name: "transactionData", parent: name, pattern: "^[0-9a-fA-F]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case authRequestCryptogram = "AuthRequestCryptogram"
            case authResponseAttributes = "AuthResponseAttributes"
            case keyIdentifier = "KeyIdentifier"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case sessionKeyDerivationAttributes = "SessionKeyDerivationAttributes"
            case transactionData = "TransactionData"
        }
    }

    public struct VerifyAuthRequestCryptogramOutput: AWSDecodableShape {
        /// The result for ARQC verification or ARPC generation within Amazon Web Services Payment Cryptography.
        public let authResponseValue: String?
        /// The keyARN of the major encryption key that Amazon Web Services Payment Cryptography uses for ARQC verification.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String

        @inlinable
        public init(authResponseValue: String? = nil, keyArn: String, keyCheckValue: String) {
            self.authResponseValue = authResponseValue
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case authResponseValue = "AuthResponseValue"
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
        }
    }

    public struct VerifyCardValidationDataInput: AWSEncodableShape {
        /// The keyARN of the CVK encryption key that Amazon Web Services Payment Cryptography uses to verify card data.
        public let keyIdentifier: String
        /// The Primary Account Number (PAN), a unique identifier for a payment credit or debit card that associates the card with a specific account holder.
        public let primaryAccountNumber: String
        /// The CVV or CSC value for use for card data verification within Amazon Web Services Payment Cryptography.
        public let validationData: String
        /// The algorithm to use for verification of card data within Amazon Web Services Payment Cryptography.
        public let verificationAttributes: CardVerificationAttributes

        @inlinable
        public init(keyIdentifier: String, primaryAccountNumber: String, validationData: String, verificationAttributes: CardVerificationAttributes) {
            self.keyIdentifier = keyIdentifier
            self.primaryAccountNumber = primaryAccountNumber
            self.validationData = validationData
            self.verificationAttributes = verificationAttributes
        }

        public func validate(name: String) throws {
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.validationData, name: "validationData", parent: name, max: 5)
            try self.validate(self.validationData, name: "validationData", parent: name, min: 3)
            try self.validate(self.validationData, name: "validationData", parent: name, pattern: "^[0-9]+$")
            try self.verificationAttributes.validate(name: "\(name).verificationAttributes")
        }

        private enum CodingKeys: String, CodingKey {
            case keyIdentifier = "KeyIdentifier"
            case primaryAccountNumber = "PrimaryAccountNumber"
            case validationData = "ValidationData"
            case verificationAttributes = "VerificationAttributes"
        }
    }

    public struct VerifyCardValidationDataOutput: AWSDecodableShape {
        /// The keyARN of the CVK encryption key that Amazon Web Services Payment Cryptography uses to verify CVV or CSC.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String

        @inlinable
        public init(keyArn: String, keyCheckValue: String) {
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
        }
    }

    public struct VerifyMacInput: AWSEncodableShape {
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses to verify MAC data.
        public let keyIdentifier: String
        /// The MAC being verified.
        public let mac: String
        /// The length of the MAC.
        public let macLength: Int?
        /// The data on for which MAC is under verification. This value must be hexBinary.
        public let messageData: String
        /// The attributes and data values to use for MAC verification within Amazon Web Services Payment Cryptography.
        public let verificationAttributes: MacAttributes

        @inlinable
        public init(keyIdentifier: String, mac: String, macLength: Int? = nil, messageData: String, verificationAttributes: MacAttributes) {
            self.keyIdentifier = keyIdentifier
            self.mac = mac
            self.macLength = macLength
            self.messageData = messageData
            self.verificationAttributes = verificationAttributes
        }

        public func validate(name: String) throws {
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, max: 322)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, min: 7)
            try self.validate(self.keyIdentifier, name: "keyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.validate(self.mac, name: "mac", parent: name, max: 128)
            try self.validate(self.mac, name: "mac", parent: name, min: 4)
            try self.validate(self.mac, name: "mac", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.validate(self.macLength, name: "macLength", parent: name, max: 16)
            try self.validate(self.macLength, name: "macLength", parent: name, min: 4)
            try self.validate(self.messageData, name: "messageData", parent: name, max: 8192)
            try self.validate(self.messageData, name: "messageData", parent: name, min: 2)
            try self.validate(self.messageData, name: "messageData", parent: name, pattern: "^(?:[0-9a-fA-F][0-9a-fA-F])+$")
            try self.verificationAttributes.validate(name: "\(name).verificationAttributes")
        }

        private enum CodingKeys: String, CodingKey {
            case keyIdentifier = "KeyIdentifier"
            case mac = "Mac"
            case macLength = "MacLength"
            case messageData = "MessageData"
            case verificationAttributes = "VerificationAttributes"
        }
    }

    public struct VerifyMacOutput: AWSDecodableShape {
        /// The keyARN of the encryption key that Amazon Web Services Payment Cryptography uses for MAC verification.
        public let keyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let keyCheckValue: String

        @inlinable
        public init(keyArn: String, keyCheckValue: String) {
            self.keyArn = keyArn
            self.keyCheckValue = keyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case keyArn = "KeyArn"
            case keyCheckValue = "KeyCheckValue"
        }
    }

    public struct VerifyPinDataInput: AWSEncodableShape {
        /// The attributes and values for the DUKPT encrypted PIN block data.
        public let dukptAttributes: DukptAttributes?
        /// The encrypted PIN block data that Amazon Web Services Payment Cryptography verifies.
        public let encryptedPinBlock: String
        /// The keyARN of the encryption key under which the PIN block data is encrypted. This key type can be PEK or BDK.
        public let encryptionKeyIdentifier: String
        public let encryptionWrappedKey: WrappedKey?
        /// The PIN encoding format for pin data generation as specified in ISO 9564. Amazon Web Services Payment Cryptography supports ISO_Format_0 and ISO_Format_3. The ISO_Format_0 PIN block format is equivalent to the ANSI X9.8, VISA-1, and ECI-1 PIN block formats. It is similar to a VISA-4 PIN block format. It supports a PIN from 4 to 12 digits in length. The ISO_Format_3 PIN block format is the same as ISO_Format_0 except that the fill digits are random values from 10 to 15.
        public let pinBlockFormat: PinBlockFormatForPinData
        /// The length of PIN being verified.
        public let pinDataLength: Int?
        /// The Primary Account Number (PAN), a unique identifier for a payment credit or debit card that associates the card with a specific account holder.
        public let primaryAccountNumber: String
        /// The attributes and values for PIN data verification.
        public let verificationAttributes: PinVerificationAttributes
        /// The keyARN of the PIN verification key.
        public let verificationKeyIdentifier: String

        @inlinable
        public init(dukptAttributes: DukptAttributes? = nil, encryptedPinBlock: String, encryptionKeyIdentifier: String, encryptionWrappedKey: WrappedKey? = nil, pinBlockFormat: PinBlockFormatForPinData, pinDataLength: Int? = nil, primaryAccountNumber: String, verificationAttributes: PinVerificationAttributes, verificationKeyIdentifier: String) {
            self.dukptAttributes = dukptAttributes
            self.encryptedPinBlock = encryptedPinBlock
            self.encryptionKeyIdentifier = encryptionKeyIdentifier
            self.encryptionWrappedKey = encryptionWrappedKey
            self.pinBlockFormat = pinBlockFormat
            self.pinDataLength = pinDataLength
            self.primaryAccountNumber = primaryAccountNumber
            self.verificationAttributes = verificationAttributes
            self.verificationKeyIdentifier = verificationKeyIdentifier
        }

        public func validate(name: String) throws {
            try self.dukptAttributes?.validate(name: "\(name).dukptAttributes")
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, max: 32)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, min: 16)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.encryptionKeyIdentifier, name: "encryptionKeyIdentifier", parent: name, max: 322)
            try self.validate(self.encryptionKeyIdentifier, name: "encryptionKeyIdentifier", parent: name, min: 7)
            try self.validate(self.encryptionKeyIdentifier, name: "encryptionKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.encryptionWrappedKey?.validate(name: "\(name).encryptionWrappedKey")
            try self.validate(self.pinDataLength, name: "pinDataLength", parent: name, max: 12)
            try self.validate(self.pinDataLength, name: "pinDataLength", parent: name, min: 4)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
            try self.verificationAttributes.validate(name: "\(name).verificationAttributes")
            try self.validate(self.verificationKeyIdentifier, name: "verificationKeyIdentifier", parent: name, max: 322)
            try self.validate(self.verificationKeyIdentifier, name: "verificationKeyIdentifier", parent: name, min: 7)
            try self.validate(self.verificationKeyIdentifier, name: "verificationKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case dukptAttributes = "DukptAttributes"
            case encryptedPinBlock = "EncryptedPinBlock"
            case encryptionKeyIdentifier = "EncryptionKeyIdentifier"
            case encryptionWrappedKey = "EncryptionWrappedKey"
            case pinBlockFormat = "PinBlockFormat"
            case pinDataLength = "PinDataLength"
            case primaryAccountNumber = "PrimaryAccountNumber"
            case verificationAttributes = "VerificationAttributes"
            case verificationKeyIdentifier = "VerificationKeyIdentifier"
        }
    }

    public struct VerifyPinDataOutput: AWSDecodableShape {
        /// The keyARN of the PEK that Amazon Web Services Payment Cryptography uses for encrypted pin block generation.
        public let encryptionKeyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let encryptionKeyCheckValue: String
        /// The keyARN of the PIN encryption key that Amazon Web Services Payment Cryptography uses for PIN or PIN Offset verification.
        public let verificationKeyArn: String
        /// The key check value (KCV) of the encryption key. The KCV is used to check if all parties holding a given key have the same key or to detect that a key has changed. Amazon Web Services Payment Cryptography computes the KCV according to the CMAC specification.
        public let verificationKeyCheckValue: String

        @inlinable
        public init(encryptionKeyArn: String, encryptionKeyCheckValue: String, verificationKeyArn: String, verificationKeyCheckValue: String) {
            self.encryptionKeyArn = encryptionKeyArn
            self.encryptionKeyCheckValue = encryptionKeyCheckValue
            self.verificationKeyArn = verificationKeyArn
            self.verificationKeyCheckValue = verificationKeyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionKeyArn = "EncryptionKeyArn"
            case encryptionKeyCheckValue = "EncryptionKeyCheckValue"
            case verificationKeyArn = "VerificationKeyArn"
            case verificationKeyCheckValue = "VerificationKeyCheckValue"
        }
    }

    public struct VisaAmexDerivationOutputs: AWSDecodableShape {
        /// The keyArn of the issuer master key for cryptogram (IMK-AC) used by the operation.
        public let authorizationRequestKeyArn: String
        /// The key check value (KCV) of the issuer master key for cryptogram (IMK-AC) used by the operation.
        public let authorizationRequestKeyCheckValue: String
        /// The keyArn of the current PIN PEK.
        public let currentPinPekArn: String?
        /// The key check value (KCV) of the current PIN PEK.
        public let currentPinPekKeyCheckValue: String?

        @inlinable
        public init(authorizationRequestKeyArn: String, authorizationRequestKeyCheckValue: String, currentPinPekArn: String? = nil, currentPinPekKeyCheckValue: String? = nil) {
            self.authorizationRequestKeyArn = authorizationRequestKeyArn
            self.authorizationRequestKeyCheckValue = authorizationRequestKeyCheckValue
            self.currentPinPekArn = currentPinPekArn
            self.currentPinPekKeyCheckValue = currentPinPekKeyCheckValue
        }

        private enum CodingKeys: String, CodingKey {
            case authorizationRequestKeyArn = "AuthorizationRequestKeyArn"
            case authorizationRequestKeyCheckValue = "AuthorizationRequestKeyCheckValue"
            case currentPinPekArn = "CurrentPinPekArn"
            case currentPinPekKeyCheckValue = "CurrentPinPekKeyCheckValue"
        }
    }

    public struct VisaAttributes: AWSEncodableShape {
        /// The transaction counter of the current transaction that is provided by the terminal during transaction processing.
        public let applicationTransactionCounter: String
        /// The keyArn of the issuer master key for cryptogram (IMK-AC) for the payment card.
        public let authorizationRequestKeyIdentifier: String
        /// The encrypted pinblock of the old pin stored on the chip card.
        public let currentPinAttributes: CurrentPinAttributes?
        /// The method to use when deriving the master key for the payment card.
        public let majorKeyDerivationMode: MajorKeyDerivationMode
        /// A number that identifies and differentiates payment cards with the same Primary Account Number (PAN). Typically 00 is used, if no value is provided by the terminal.
        public let panSequenceNumber: String
        /// The Primary Account Number (PAN) of the cardholder.
        public let primaryAccountNumber: String

        @inlinable
        public init(applicationTransactionCounter: String, authorizationRequestKeyIdentifier: String, currentPinAttributes: CurrentPinAttributes? = nil, majorKeyDerivationMode: MajorKeyDerivationMode, panSequenceNumber: String, primaryAccountNumber: String) {
            self.applicationTransactionCounter = applicationTransactionCounter
            self.authorizationRequestKeyIdentifier = authorizationRequestKeyIdentifier
            self.currentPinAttributes = currentPinAttributes
            self.majorKeyDerivationMode = majorKeyDerivationMode
            self.panSequenceNumber = panSequenceNumber
            self.primaryAccountNumber = primaryAccountNumber
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, max: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, min: 4)
            try self.validate(self.applicationTransactionCounter, name: "applicationTransactionCounter", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.authorizationRequestKeyIdentifier, name: "authorizationRequestKeyIdentifier", parent: name, max: 322)
            try self.validate(self.authorizationRequestKeyIdentifier, name: "authorizationRequestKeyIdentifier", parent: name, min: 7)
            try self.validate(self.authorizationRequestKeyIdentifier, name: "authorizationRequestKeyIdentifier", parent: name, pattern: "^arn:aws:payment-cryptography:[a-z]{2}-[a-z]{1,16}-[0-9]+:[0-9]{12}:(key/[0-9a-zA-Z]{16,64}|alias/[a-zA-Z0-9/_-]+)$|^alias/[a-zA-Z0-9/_-]+$")
            try self.currentPinAttributes?.validate(name: "\(name).currentPinAttributes")
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, max: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, min: 2)
            try self.validate(self.panSequenceNumber, name: "panSequenceNumber", parent: name, pattern: "^[0-9]+$")
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, max: 19)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, min: 12)
            try self.validate(self.primaryAccountNumber, name: "primaryAccountNumber", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationTransactionCounter = "ApplicationTransactionCounter"
            case authorizationRequestKeyIdentifier = "AuthorizationRequestKeyIdentifier"
            case currentPinAttributes = "CurrentPinAttributes"
            case majorKeyDerivationMode = "MajorKeyDerivationMode"
            case panSequenceNumber = "PanSequenceNumber"
            case primaryAccountNumber = "PrimaryAccountNumber"
        }
    }

    public struct VisaPin: AWSEncodableShape {
        /// The value for PIN verification index. It is used in the Visa PIN algorithm to calculate the PVV (PIN Verification Value).
        public let pinVerificationKeyIndex: Int

        @inlinable
        public init(pinVerificationKeyIndex: Int) {
            self.pinVerificationKeyIndex = pinVerificationKeyIndex
        }

        public func validate(name: String) throws {
            try self.validate(self.pinVerificationKeyIndex, name: "pinVerificationKeyIndex", parent: name, max: 6)
            try self.validate(self.pinVerificationKeyIndex, name: "pinVerificationKeyIndex", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case pinVerificationKeyIndex = "PinVerificationKeyIndex"
        }
    }

    public struct VisaPinVerification: AWSEncodableShape {
        /// The value for PIN verification index. It is used in the Visa PIN algorithm to calculate the PVV (PIN Verification Value).
        public let pinVerificationKeyIndex: Int
        /// Parameters that are required to generate or verify Visa PVV (PIN Verification Value).
        public let verificationValue: String

        @inlinable
        public init(pinVerificationKeyIndex: Int, verificationValue: String) {
            self.pinVerificationKeyIndex = pinVerificationKeyIndex
            self.verificationValue = verificationValue
        }

        public func validate(name: String) throws {
            try self.validate(self.pinVerificationKeyIndex, name: "pinVerificationKeyIndex", parent: name, max: 6)
            try self.validate(self.pinVerificationKeyIndex, name: "pinVerificationKeyIndex", parent: name, min: 0)
            try self.validate(self.verificationValue, name: "verificationValue", parent: name, max: 12)
            try self.validate(self.verificationValue, name: "verificationValue", parent: name, min: 4)
            try self.validate(self.verificationValue, name: "verificationValue", parent: name, pattern: "^[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case pinVerificationKeyIndex = "PinVerificationKeyIndex"
            case verificationValue = "VerificationValue"
        }
    }

    public struct VisaPinVerificationValue: AWSEncodableShape {
        /// The encrypted PIN block data to verify.
        public let encryptedPinBlock: String
        /// The value for PIN verification index. It is used in the Visa PIN algorithm to calculate the PVV (PIN Verification Value).
        public let pinVerificationKeyIndex: Int

        @inlinable
        public init(encryptedPinBlock: String, pinVerificationKeyIndex: Int) {
            self.encryptedPinBlock = encryptedPinBlock
            self.pinVerificationKeyIndex = pinVerificationKeyIndex
        }

        public func validate(name: String) throws {
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, max: 32)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, min: 16)
            try self.validate(self.encryptedPinBlock, name: "encryptedPinBlock", parent: name, pattern: "^[0-9a-fA-F]+$")
            try self.validate(self.pinVerificationKeyIndex, name: "pinVerificationKeyIndex", parent: name, max: 6)
            try self.validate(self.pinVerificationKeyIndex, name: "pinVerificationKeyIndex", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case encryptedPinBlock = "EncryptedPinBlock"
            case pinVerificationKeyIndex = "PinVerificationKeyIndex"
        }
    }

    public struct WrappedKey: AWSEncodableShape {
        /// The algorithm that Amazon Web Services Payment Cryptography uses to calculate the key check value (KCV). It is used to validate the key integrity. For TDES keys, the KCV is computed by encrypting 8 bytes, each with value of zero, with the key to be checked and retaining the 3 highest order bytes of the encrypted result. For AES keys, the KCV is computed using a CMAC algorithm where the input data is 16 bytes of zero and retaining the 3 highest order bytes of the encrypted result.
        public let keyCheckValueAlgorithm: KeyCheckValueAlgorithm?
        /// Parameter information of a WrappedKeyBlock for encryption key exchange.
        public let wrappedKeyMaterial: WrappedKeyMaterial

        @inlinable
        public init(keyCheckValueAlgorithm: KeyCheckValueAlgorithm? = nil, wrappedKeyMaterial: WrappedKeyMaterial) {
            self.keyCheckValueAlgorithm = keyCheckValueAlgorithm
            self.wrappedKeyMaterial = wrappedKeyMaterial
        }

        public func validate(name: String) throws {
            try self.wrappedKeyMaterial.validate(name: "\(name).wrappedKeyMaterial")
        }

        private enum CodingKeys: String, CodingKey {
            case keyCheckValueAlgorithm = "KeyCheckValueAlgorithm"
            case wrappedKeyMaterial = "WrappedKeyMaterial"
        }
    }
}

// MARK: - Errors

/// Error enum for PaymentCryptographyData
public struct PaymentCryptographyDataErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
        case verificationFailedException = "VerificationFailedException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize PaymentCryptographyData
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The request processing has failed because of an unknown error, exception, or failure.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The request was denied due to an invalid resource error.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The request was denied due to an invalid request error.
    public static var validationException: Self { .init(.validationException) }
    /// This request failed verification.
    public static var verificationFailedException: Self { .init(.verificationFailedException) }
}

extension PaymentCryptographyDataErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ResourceNotFoundException": PaymentCryptographyData.ResourceNotFoundException.self,
        "ValidationException": PaymentCryptographyData.ValidationException.self,
        "VerificationFailedException": PaymentCryptographyData.VerificationFailedException.self
    ]
}

extension PaymentCryptographyDataErrorType: Equatable {
    public static func == (lhs: PaymentCryptographyDataErrorType, rhs: PaymentCryptographyDataErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension PaymentCryptographyDataErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
